[AIR16.0] AIR for iOS でハマったこと (2)

AIR for iOS アプリ を iPad Air 2 (iOS 8.3) にインストールしようとして、ハマったことをメモしておくね。 :bouzu:

AIR SDK 16.0.0.292 [ASC2.0] を使ったよ。 :boy:

loader_iOS_case2

:caution: 要 Flash Player 11.8 以上

次のような構造にして、app.swf を loader.swf に読み込む。

loader_iOS_case2_directory

Main.as (loader.swf)
package {

  import flash.display.Sprite;
  import flash.display.Loader;
  import flash.display.LoaderInfo;
  import flash.net.URLRequest;
  import flash.events.Event;

  import controls.Btn;

  [SWF(backgroundColor="#FFFFFF", width="600", height="800", frameRate="30")]

  public class Main extends Sprite {
    // プロパティ
    private var container:Sprite;
    private var controller:Sprite;
    private var button:Btn;
    private var loader:Loader;
    private static var filePath:String = "assets/app.swf";

    // コンストラクタ
    public function Main() {
      init();
    }

    // メソッド
    private function init():void {
      container = new Sprite();
      addChild(container);
      controller = new Sprite();
      addChild(controller);
      controller.y = 720;
      button = new Btn();
      controller.addChild(button);
      button.addEventListener(MouseEvent.CLICK, click, false, 0, true);
      loader = new Loader();
    }
    private function click(evt:MouseEvent):void {
      loader.contentLoaderInfo.addEventListener(Event.COMPLETE, complete, false, 0, true);
      try {
        loader.load(new URLRequest(filePath));
      } catch (err:Error) {
        trace(err.message);
      }
    }
    private function complete(evt:Event):void {
      loader.contentLoaderInfo.removeEventListener(Event.COMPLETE, complete);
      container.addChild(Sprite(evt.target.content));
    }

  }

}

これで、ちゃんと appA.swf, appB.swf, appC.swf が読み込めている。loader.ipa をインストールすることもできた。
が! ボタンを押しても、何も表示されない! :rain:

どうやら、こんなエラーが発生している模様。
Error #3747: Multiple application domains are not supported on this operating system.


Main.as (loader.swf)
package {

  import flash.display.Sprite;
  import flash.display.Loader;
  import flash.display.LoaderInfo;
  import flash.net.URLRequest;
  import flash.events.Event;

  import flash.system.LoaderContext;
  import flash.system.ApplicationDomain;

  import controls.Btn;

  [SWF(backgroundColor="#FFFFFF", width="600", height="800", frameRate="30")]

  public class Main extends Sprite {
    // プロパティ
    private var container:Sprite;
    private var controller:Sprite;
    private var button:Btn;
    private var loader:Loader;
    private static var filePath:String = "assets/app.swf";

    // コンストラクタ
    public function Main() {
      init();
    }

    // メソッド
    private function init():void {
      container = new Sprite();
      addChild(container);
      controller = new Sprite();
      addChild(controller);
      controller.y = 720;
      button = new Btn();
      controller.addChild(button);
      button.addEventListener(MouseEvent.CLICK, click, false, 0, true);
      loader = new Loader();
    }
    private function click(evt:MouseEvent):void {
      loader.contentLoaderInfo.addEventListener(Event.COMPLETE, loaded, false, 0, true);
      try {
        var context:LoaderContext = new LoaderContext(false, ApplicationDomain.currentDomain, null);
        loader.load(new URLRequest(filePath), context);
      } catch (err:Error) {
        trace(err.message);
      }
    }
    private function loaded(evt:Event):void {
      loader.contentLoaderInfo.removeEventListener(Event.COMPLETE, loaded);
      container.addChild(Sprite(evt.target.content));
    }

  }

}

Terminal を起動して、
$ cd /Users/****/development
$ ./bin/adt -package -target ipa-ad-hoc -useLegacyAOT no -storetype pkcs12 -keystore ios_distribution.p12 -storepass **** -provisioning-profile Distribution.mobileprovision loader.ipa loader-app.xml loader.swf assets icons
$ ./bin/adt -installApp -platform ios -package loader.ipa
と入力する。

ボタンを押すと、app.swf が表示された! :sun:


参考資料「Loader - Adobe ActionScript® 3(AS3)API リファレンス
iOS での AIR アプリケーションでは、アプリケーションパッケージからロードする場合のみ、ActionScript を含む SWF ファイルをロードできます。この制約では、ActionScript 向けに書き出されたクラス名を含むアセットなどの、あらゆる ActionScript が対象となります。あらゆる SWF ファイルをロードするためには、以下の例のように、親 SWF と同じアプリケーションドメインを使用して SWF をロードする必要があります。

つまり、LoaderContext, ApplicationDomainクラスを使えと。