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

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

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

loader_iOS_case6

:caution: 要 Flash Player 11.8 以上

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

loader_iOS_case6_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 flash.system.LoaderContext;
  import flash.system.ApplicationDomain;

  import controls.Btn;
  import scenes.IContent;

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

  public class Main extends Sprite {
    // プロパティ
    private var container:Sprite;
    private var controller:Sprite;
    private var buttons:Array;
    private var selectedId:int = -1;
    private var loader:Loader;
    private static var basePath:String = "assets/";
    private static var files:Array = ["appA.swf", "appB.swf", "appC.swf"];
    private var contents:Array;

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

    // メソッド
    private function init():void {
      container = new Sprite();
      addChild(container);
      controller = new Sprite();
      addChild(controller);
      controller.y = 720;
      buttons = [];
      for (var n:uint = 0; n < max; n++) {
        var button:Btn = new Btn();
        controller.addChild(button);
        button.id = n;
        button.addEventListener(MouseEvent.CLICK, click, false, 0, true);
      }
      contents = [];
      loader = new Loader();
    }
    private function click(evt:MouseEvent):void {
      selectedId = evt.target.id;
      for (var n:uint = 0; n < max; n++) {
        var button:Btn = buttons[n];
        button.selected = (n == selectedId);
      }
      if (!contents[selectedId]) {
        load(selectedId);
      } else {
        show(selectedId);
      }
    }
    private function load(id:uint):void {
      loader.contentLoaderInfo.addEventListener(Event.COMPLETE, loaded, false, 0, true);
      try {
        var context:LoaderContext = new LoaderContext(false, ApplicationDomain.currentDomain, null);
        var filePath:String = basePath + files[id];
        loader.load(new URLRequest(filePath), context);
      } catch (err:Error) {
        trace(err.message);
      }
    }
    private function loaded(evt:Event):void {
      loader.contentLoaderInfo.removeEventListener(Event.COMPLETE, loaded);
      contents[selectedId] = loader.content;
      show(selectedId);
    }
    private function show(id:uint):void {
      var content:IContent = contents[id];
      content.reset();
      container.removeChildren();
      container.addChild(Sprite(content));
    }

  }

}

AppA.as (appA.swf)
package {

  import flash.display.Sprite;
  import views.BasicView;
  import views.MainView;
  import controls.Button;

  import scenes.IContent;

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

  public class AppA extends Sprite implements IContent {
    // プロパティ
    private var button:Button;
    private var view:MainView;

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

    // メソッド
    private function init():void {
      var basic:BasicView = new BasicView(0xB2E1FF, "AppAlication A");
      addChild(basic);
      button = new Button();
      addChild(button);
      button.addEventListener(MouseEvent.CLICK, open, false, 0, true);
      view = new MainView();
      addChild(view);
      view.show("AppAlication A");
      view.alpha = 0;
      view.visible = false;
    }
    public function start():void {
    }
    public function stop():void {
    }
    public function reset():void {
      view.alpha = 0;
      view.visible = false;
      button.addEventListener(MouseEvent.CLICK, open, false, 0, true);
      button.enabled = true;
      view.removeEventListener(MouseEvent.CLICK, close);
    }
    private function open(evt:MouseEvent):void {
      (中略)
    }
    private function close(evt:MouseEvent):void {
      (中略)
    }

  }

}

IContent.as (scenes.IContent.as)
package scenes {

  public interface IContent {

    // メソッド
    function start():void;
    function stop():void;
    function reset():void;

  }

}

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
と入力する。

これで、ちゃんと appA.swf, appB.swf, appC.swf が読み込めている。loader.ipa をインストールすることもできた。
ボタンを何度押しても、SWFファイルは読み込める。 :sun:

一度読み込んだSWFファイルはプールしておいて、使い回すようにしてみた。 :girl:
interface 実装した。初期化メソッド(reset)を用意して、コンテンツ表示直前に実行してある。 :beer: