Kousei Ikeda/Blog

2012.10.23/Movie

京都の時代祭っていうおまつりをオフィスから撮ってみた。
音楽は谷口彩子さん。

HDのがキレイだからHDで見てね。

Jidai Matsuri 2012 in Kyoto, A Short Timelapse Film from ikekou on Vimeo.

Jidai Matsuri 2012-1
Jidai Matsuri 2012-2
Jidai Matsuri 2012-3
Jidai Matsuri 2012-4
Jidai Matsuri 2012-5
Jidai Matsuri 2012-6
Jidai Matsuri 2012-7
Jidai Matsuri 2012-8
Jidai Matsuri 2012-9

Jidai Matsuri 2012, A Short Timelapse Film – https://vimeo.com/51971924

2012.10.12/Development

[ 2012.12.3追記 ]
ANEの”A”が”Adobe”なのか”AIR”なのか”ActionScript”なのか自分の中で曖昧だったのですが、kamijo先生が”ActionScript Native Extensions”と書いてらっしゃる記事を見かけたのでタイトルをなおしました。

ANEでHelloWorldをする手順を自分なりにまとめてみる。
忘れるので。
adlやシミュレーターにも対応してる。

前提

SDKのディレクトリ

/Users/kouseiikeda/Dev/Flash/SDK/flex_sdk_4.6_air_3.4

今回の作業ディレクトリ
DropBoxにつっこんでます。適宜読み替えて。

/Users/kouseiikeda/Dropbox/AIR/Samples/AIR_HelloWorldANE_test

今回作るもの

目標設定。こういうANEを作る。

  • ANEはHelloWorldANE.getHelloWorld()というメソッドを持つ
  • メソッドを実行すると”HelloWorld [プラットフォーム別文字列]”という文字列を返す、というANE
  • Flashのパブリッシュプレビュー(ADL)、iOSデバイス、iOSシミュレーターで実行できる
  • それぞれの実行環境で異なる動作をさせる
  • ADLでは”HelloWorld ADL”という文字列を戻す
  • iOSデバイスでは”HelloWorld iOS”という文字列を戻す
  • iOSシミュレーターでは”HelloWorld iOS Simulator”、という文字列を戻す

おおまかな手順

最初に全体の手順を。

  1. ASでインターフェースとなるクラスを作る
  2. SWCを作る
  3. HelloWorldANE.aを作るためにXCodeでProjectを作る
  4. FlashRuntimeExtensions.hをビルドパスに設定する
  5. HelloWorldANE.hを作成
  6. HelloWorldANE.mを作成
  7. ビルドしてiOS用のHelloWorldANE.aをdeployにコピー
  8. iOS Simulator用にちょっと書き換えてビルドしてコピー
  9. iOS用のlibrary.swfを作るためににASを書く
  10. iOS用のSWC(library.swf)を作る
  11. iOS Simulator用のSWC(library.swf)を作る
  12. ADL用のSWC(library.swf)を作る
  13. extension.xmlを書く
  14. ANEパッケージング

ディレクトリ構成

先に全体像がわかったほうがしっくりくると思うので最終的な作業ディレクトリの中身。自分なりにわかるやすく分けただけなのでこれも別に決まりではない。ディレクトリを作る手順を省いている箇所もあるので適宜自分で作る。

AIR_HelloWorldANE_test/
  build_ane.bash
  as/
    build_swc_default.bash
    build_swc_ios.bash
    build_swc_iossimulator.bash
    build_swc.bash
    deploy/
      HelloWorldANE.swc
    deploy_default/
      catalog.xml
      HelloWorldANE.swc
      library.swf
    deploy_ios/
      catalog.xml
      HelloWorldANE.swc
      library.swf
    deploy_iossimulator/
      catalog.xml
      HelloWorldANE.swc
      library.swf
    src/
      jp/
        ikekou/
          ane/
            HelloWorldANE.as
    src_default/
      jp/
        ikekou/
          ane/
            HelloWorldANE.as
    src_ios/
      jp/
        ikekou/
          ane/
            HelloWorldANE.as
    src_iossimulator/
      jp/
        ikekou/
          ane/
            HelloWorldANE.as
  deploy/
    extension.xml
    HelloWorldANE.ane
    HelloWorldANE.swc
    platform/
      default/
        library.swf
      ios/
        libHelloWorldANE.a
        library.swf
      iossimulator/
        libHelloWorldANE.a
        library.swf
  ios/
    HelloWorldANE/
      HelloWorldANE.xcodeproj
      (etc)
  test/
    AIR_HelloWorldANE_test.fla

1. ASでインターフェースとなるクラスを作る

こっから先は手順。
インターフェースをもとにメソッドの中身はからっぽでいいのでASを書く。

//HelloWorldANE.as

package jp.ikekou.ane
{
     public class HelloWorldANE
     {

          public function isSupported():Boolean
          {
               return false;
          }

          public function getHelloWorld():String
          {
               return "";
          }

          public function dispose():void
          {
          }
     }
}

2. SWCを作る

build_swc.bash作成
実行権限なかったら与える(以下一緒)

chmod u+x /Users/kouseiikeda/Dropbox/AIR/Samples/AIR_HelloWorldANE_test/as/build_swc.bash

コンパイルして
AIR_HelloWorldANE_test/deploy
にコピーする

#build_swc.bash

acompc_directory="/Users/kouseiikeda/Dev/Flash/SDK/flex_sdk_4.6_air_3.4/bin"
home_directory="/Users/kouseiikeda/Dropbox/AIR/Samples/AIR_HelloWorldANE_test/as"
source_directory="${home_directory}/src"
include_classes="jp.ikekou.ane.HelloWorldANE"
output_directory="${home_directory}/deploy"
swc_name="HelloWorldANE.swc"
swc_version="14"
output_path="${output_directory}/${swc_name}"
$acompc_directory/acompc -source-path $source_directory -include-classes $include_classes -swf-version $swc_version -output $output_path

cp $output_path $home_directory/../deploy

swc_versionは場合によって変わるので適宜変更。
extension.xmlで指定する名前空間と関わって来る。

3. HelloWorldANE.aを作るためにXCodeでProjectを作る

XCode起動
File -> New Project
iOS -> Framework & Library -> Cocoa Touch Static Library -> Next
Product Name -> HelloWorldANE
Company Identifier -> jp.ikekou (適当でいい)
Include Unit Tests -> チェック外す
Use Automatic Reference Counting -> チェック外す
Next -> AIR_HelloWorldANE_test/iosに保存

4. FlashRuntimeExtensions.hをビルドパスに設定する

プロジェクトのコンテキストメニュー -> Add Files to “HelloWorldANE”…
/Users/kouseiikeda/Dev/Flash/SDK/flex_sdk_4.6_air_3.4/include/FlashRuntimeExtensions.h -> 選択
Copy items into destination group’s folder (if needed) -> チェック入れる

5. HelloWorldANE.hを書く

//HelloWorldANE.h

#import "FlashRuntimeExtensions.h"

/*
 ネイティブ拡張関数
 */
FREObject HelloWorldANEGetHelloWorld(
                                     FREContext ctx,
                                     void* funcData,
                                     uint32_t argc,
                                     FREObject arg[]
                                     );

/*
 ネイティブ拡張コンテキストの初期化関数
 */
void HelloWorldANEContextInitializer(
                                     void* extData,
                                     const uint8_t* ctxType,
                                     FREContext ctx,
                                     uint32_t* numFunctionsToTest,
                                     const FRENamedFunction** functionsToSet
                                     );
/*
 ネイティブ拡張コンテキストの破棄関数
 */

void HelloWorldANEContextFinalizer(
                                   FREContext ctx
                                   );

/*
 ネイティブ拡張の初期化関数
 */
void HelloWorldANEExtInitializer(
                                 void** extDataToSet,
                                 FREContextInitializer* ctxInitializerToSet,
                                 FREContextFinalizer* ctxFinalizerToSet
                                 );

/*
 ネイティブ拡張の破棄関数
 */
void HelloWorldANEExtFinalizer(
                               void* extData
                               );

ネイティブ拡張の初期化関数と破棄関数は、名前にアンダーバーが入っているとダメらしい。
HelloWorldANE_ExtInitializerみたくしたかったんだけど
最後の*.aneのパッケージングの所でコケた。
ドキュメントのどこに書いてあるのかはまだ見つけれてない。

あと複数のANEで初期化関数の名前とかがかぶるとダメらしいので適当な接頭辞をつけたほうがいいよう。今回はHelloWorldANE+hoge。
参考 : 複数の自作ANEを作る際の注意点: 鈴木くにのブログ

6. HelloWorldANE.mを書く

//HelloWorldANE.m

#import "HelloWorldANE.m"

/*
 ◆ネイティブ拡張関数の作成
 ネイティブ拡張関数は、ヘッダーファイルに定義されているFREFunction関数型で実装する必要があります
 ネイティブ拡張関数とは、ActionScript側からネイティブ拡張コンテキスト(次の項目を参照)経由で
 呼び出すことができる関数のことです。
 FREFunction関数型は、下表の通りです。
 このネイティブ拡張関数は、ネイティブ拡張コンテキストに登録して、ActionScriptから呼び出されます。
 */

/*
 ◇FREFunction
 この関数型の引数と同じ関数を作成して、その中にロジックを記述します。
 ActionScirptにデータを返したい場合は、FREObjectに変換して返り値にします。引数は下記の通りです。
 ・argc
 ネイティブ拡張関数の引数の数。
 ・argv
 ネイティブ拡張関数の引数の配列。
 */
FREObject HelloWorldANEGetHelloWorld(
                                     FREContext ctx,
                                     void* funcData,
                                     uint32_t argc,
                                     FREObject arg[]
                                     ){
    
    //サンプルでは、ActionScriptに文字列「HelloWorld」を返すために、
    //FREObject.newObjectを使ってFREObjectインスタンスを生成しています。
    const char *str = "HelloWorld iOS";
    FREObject retStr;
    FRENewObjectFromUTF8(strlen(str)+1, (const uint8_t *)str, &retStr);
    
    return retStr;
}

/*
 ◆ネイティブ拡張コンテキストの初期化関数と破棄関数の作成
 ネイティブ拡張コンテキストの初期化関数と破棄関数は、ネイティブ拡張の初期化時に必要であり
 ヘッダーファイルに定義されている関数型で実装しなければなりません。
 この初期化関数を使用して、ネイティブ拡張コンテキストに登録するネイティブ拡張関数を指定することができます。
 */

/*
 ◇FREContextInitializer
 ネイティブ拡張コンテキストが初期化されるときに呼びだされる関数。
 引数は下記の通りです。
 ・umFunctionsToTest
 ネイティブ拡張コンテキストに登録するネイティブ拡張関数の数を指定します。
 ・functionsToSet
 ネイティブ拡張コンテキストに登録するネイティブ拡張関数配列を返します。
 この配列は、型がFRENamedFunctionで、長さがnumFunctionsToTestになります。
 また、ネイティブ拡張コンテキスト内部で登録されます。
 
 ◇FRENamedFunction型
 ネイティブ拡張関数を登録する際に使用します。
 引数は下記の通りです。
 ・name
 ネイティブ拡張関数名を指定します。
 ・functionData
 ネイティブ関数に渡すデータのポインタを指定します。
 ・function
 ネイティブ関数のポインタを指定します。
 */
void HelloWorldANEContextInitializer(
                                     void* extData,
                                     const uint8_t* ctxType,
                                     FREContext ctx,
                                     uint32_t* numFunctionsToTest,
                                     const FRENamedFunction** functionsToSet
                                     ){
    
    *numFunctionsToTest=1;
    
    //サンプルでは、関数名GatHelloWorldとGetHelloWorldネイティブ拡張関数を関連付けています。
    //よって、ActionScriptからGatHelloWorldをキーにして
    //GatHelloWorldネイティブ拡張関数を指定することができます。
    FRENamedFunction* func = (FRENamedFunction*)malloc(sizeof(FRENamedFunction)*1);
    func[0].name= (const uint8_t*)"HelloWorldANEGetHelloWorld"; //ネイティブ拡張関数名
    func[0].functionData=NULL;
    func[0].function=&HelloWorldANEGetHelloWorld;
    
    *functionsToSet=func;
}

/*
 ◇FREContextFinalizer
 
 ネイティブ拡張コンテキストが破棄されるときに呼びだされる関数。
 */
void HelloWorldANEContextFinalizer(
                                   FREContext ctx
                                   ){
    return;
}

/*
 ◆ネイティブ拡張の初期化関数と破棄関数の作成
 ネイティブ拡張では、初期化関数と破棄関数をネイティブ拡張ライブラリに定義する必要があり、
 ヘッダーファイルに定義されている関数型で実装しなければなりません。
 また、この2つの関数はネイティブ拡張ごとに1組作成します。
 この初期化関数を使用して、ネイティブ拡張コンテキストの初期化関数と破棄関数を登録することができます。
 */

/*
 ◇FREInitializer
 ネイティブ拡張が初期化されるときに呼びだされる関数。
 ActionScriptのExtensionContext.createExtensionContext()を呼び出すことで実行されます。
 引数は下記の通りです。
 ・ctxInitializerToSet
 ネイティブ拡張コンテキスト初期化関数のポインタを指定します。
 ・ctxFinalizerToSet
 ネイティブ拡張コンテキスト破棄関数のポインタを指定します。
 */
void HelloWorldANEExtInitializer(
                                 void** extDataToSet,
                                 FREContextInitializer* ctxInitializerToSet,
                                 FREContextFinalizer* ctxFinalizerToSet
                                 ){
    
    *extDataToSet=NULL;
    //ContextInitializer関数をネイティブ拡張コンテキストの初期化関数に指定
    *ctxInitializerToSet=&HelloWorldANEContextInitializer;
    //ContextFinalizer関数をネイティブ拡張コンテキストの破棄関数に指定
    *ctxFinalizerToSet=&HelloWorldANEContextFinalizer;
}

/*
 ◇FREFinalizer
 ネイティブ拡張が破棄されるときに呼びだされる関数。
 ActionScriptのExtensionContext.dispose()を呼び出すことで実行されます。
 */
void HelloWorldANEExtFinalizer(
                               void* extData
                               ){
    return;
}

7. ビルドしてiOS用のHelloWorldANE.aをdeployにコピー

iPhoneでBuild
Products/HelloWorldANE.a -> コンテクストメニュー -> Show in Finder
Debug-iphoneos/libHelloWorldANE.aをコピー
deploy/platform/iosディレクトリ作成
deploy/platform/iosにHelloWorldANE.aをコピペ

8. iOS Simulator用にちょっと書き換えてビルドしてコピー

iOS Siimulatorで異なる動作をするのを認したいので
HelloWorldANE_GetHelloWorldの

const char *str = "HelloWorld iOS";

const char *str = "HelloWorld iOS Simulator";

に書き換え

targetをiPhone Simulatorに変更
Build
Products/HelloWorldANE.a -> コンテクストメニュー -> Show in Finder
Debug-iphonesimulator/libHelloWorldANE.aをコピー
deploy/platform/iossimulatorディレクトリ作成
deploy/platform/iossimulatorにHelloWorldANE.aをコピペ

コンテクストメニュー -> Show in Finderをしたときに、Simulator用の*.aじゃなくてデバイス用のものが選択されてたりするので注意。

9. iOS用のlibrary.swfを作るためににASを書く

さっき作ったガワだけのASを利用してiOS用
ネイティブ拡張ライブラリを呼び出すためのActionScriptライブラリのこと
ExtensionContextクラスを使用
as/srcディレクトリをコピペしてas/src_iosディレクトリを作る
中身を書き加える

//HelloWorldANE.as

package jp.ikekou.ane
{
     import flash.external.ExtensionContext;
     import flash.system.Capabilities;

     public class HelloWorldANE
     {
          private var context:ExtensionContext;

          public function HelloWorldANE()
          {
               //ネイティブ拡張コンテキストを生成
               context=ExtensionContext.createExtensionContext('jp.ikekou.ane.HelloWorldANE','type');
          }

          public function isSupported():Boolean
          {
               return true;
          }

          public function getHelloWorld():String
          {
               //ネイティブ拡張関数を呼ぶ
               return context.call('HelloWorldANEGetHelloWorld') as String;
          }

          public function dispose():void
          {
               //ネイティブ拡張コンテキストを解放
               return context.dispose();
          }
     }
}

ExtensionContext.createExtensionContextの第一引数の文字列がextension.xmlのidで指定するものと一緒。

10. iOS用のSWC(library.swf)を作る

swcを作成

・指定するswfのバージョンについて
参考 : http://help.adobe.com/ja_JP/air/extensions/WS99209310cacd98cc2d13931c1300f2c84c7-8000.html
これを読むとAIR 3.1 は SWF Version 14にあたることがわかる。

メインアプリケーションの SWF ファイルよりも上のバージョンの SWF を拡張で使用することはできません

とあるので特別な機能を使わないなら古くしておいたほうがよいということ

・platform.xmlを使う場合の制限

platform.xml ファイルには ns.adobe.com/air/extension/3.1 名前空間が必要なので、‑platformoptions フラグを使用して ANE をパッケージ化する場合は、ns.adobe.com/air/extension/3.1 およびバージョン 14 以前の SWC を指定する必要があります。

が、今回は別に使わないので関係ない。

・文字化けの解消
adtで文字化けすることがあるから、したらなおす。
参考 : AIR Androidアプリ作成:Flash, Flash Builder 4.6 | 8-8-1:リモートデバッグ(fdb)

このときMacで文字化けが起きるときには、Flex SDKのbinフォルダにあるcompcをテキストエディタで開き、最終行に
-Dfile.encoding=UTF8
を挿入し、保存します。

これをやると、結果としてcompcが

java -Dfile.encoding=UTF8 $VMARGS $D32…(以降略)

となる。

AIR_HelloWorldANE_test/as/deploy_ios作る
build_swc_ios.bash作る

コンパイルする
zipとして解凍
library.swfを
/deploy/platform/ios
にコピー

#build_swc_ios.bash

acompc_directory="/Users/kouseiikeda/Dev/Flash/SDK/flex_sdk_4.6_air_3.4/bin"
home_directory="/Users/kouseiikeda/Dropbox/AIR/Samples/AIR_HelloWorldANE_test/as"
source_directory="${home_directory}/src_ios"
include_classes="jp.ikekou.ane.HelloWorldANE"
output_directory="${home_directory}/deploy_ios"
swc_name="HelloWorldANE.swc"
swc_version="14"
output_path="${output_directory}/${swc_name}"
$acompc_directory/acompc -source-path $source_directory -include-classes $include_classes -swf-version $swc_version -output $output_path

unzip -o -d $output_directory $output_path

cp $output_directory/library.swf $home_directory/../deploy/platform/ios

11. iOS Simulator用のSWC(library.swf)を作る

今回はiOS用の時とASのコードは同じでいいのでこの作業はいらないのだけど手順として一応

AIR_HelloWorldANE_test/as/deploy_iossimulator作る
build_swc_iossimulator.bash作る

コンパイル
zipとして解凍
library.swfを
/deploy/platform/iossimulator
にコピー

#build_swc_iossimulator.bash

acompc_directory="/Users/kouseiikeda/Dev/Flash/SDK/flex_sdk_4.6_air_3.4/bin"
home_directory="/Users/kouseiikeda/Dropbox/AIR/Samples/AIR_HelloWorldANE_test/as"
source_directory="${home_directory}/src_iossimulator"
include_classes="jp.ikekou.ane.HelloWorldANE"
output_directory="${home_directory}/deploy_iossimulator"
swc_name="HelloWorldANE.swc"
swc_version="14"
output_path="${output_directory}/${swc_name}"
$acompc_directory/acompc -source-path $source_directory -include-classes $include_classes -swf-version $swc_version -output $output_path

unzip -o -d $output_directory $output_path

cp $output_directory/library.swf $home_directory/../deploy/platform/iossimulator

12. ADL用のSWC(library.swf)を作る

AIR_HelloWorldANE_test/as/src
をコピーして
AIR_HelloWorldANE_test/as/src_default
を作る
AIR_HelloWorldANE_test/as/src_default/HelloWorldANE.as
を書き換える

//HelloWorldANE.as

package jp.ikekou.ane
{
     public class HelloWorldANE
     {

          public function isSupported():Boolean
          {
               return true;
          }

          public function getHelloWorld():String
          {
               return "HelloWorld Default";
          }

          public function dispose():void
          {
          }
     }
}

とかにする(適当)

こいつはFlashのパブリッシュプレビュー時に動作する分だから
ネイティブの値をエミュレートするような適当なコードを書いておけば
それっぽい感じで見れて良いと思っている。

/deploy/platform/default/作る
build_swc_default.bash作る

コンパイル
zipとして解凍
library.swfを
/deploy/platform/default/
にコピー

#build_swc_default.bash

acompc_directory="/Users/kouseiikeda/Dev/Flash/SDK/flex_sdk_4.6_air_3.4/bin"
home_directory="/Users/kouseiikeda/Dropbox/AIR/Samples/AIR_HelloWorldANE_test/as"
source_directory="${home_directory}/src_default"
include_classes="jp.ikekou.ane.HelloWorldANE"
output_directory="${home_directory}/deploy_default"
swc_name="HelloWorldANE.swc"
swc_version="14"
output_path="${output_directory}/${swc_name}"
$acompc_directory/acompc -source-path $source_directory -include-classes $include_classes -swf-version $swc_version -output $output_path

unzip -o -d $output_directory $output_path

cp $output_directory/library.swf $home_directory/../deploy/platform/default

13. extension.xmlを書く

extension.xml

<extension xmlns="http://ns.adobe.com/air/extension/3.1"> 
    <!-- このIDは、ActionScriptからネイティブ拡張を指定する際に使います。 -->
    <id>jp.ikekou.ane.HelloWorldANE</id> 

    <!-- バージョン -->
    <versionNumber>1.0.0</versionNumber> 

    <!-- エクステンション名 -->
    <name> 
        <text xml:lang="en_US">Hello World</text> 
        <text xml:lang="ja_JP">こんにちは 世界</text> 
    </name>
    
    <platforms>
        <!-- プラットフォームを指定します。name要素には、下記のようなプラットフォームを示す値を入れます。
        Windows-x86     Windows
        MacOS-x86     Mac OS
        Android-ARM     Android
        iPhone-ARM     iOS
        iPhone-x86
        QNX-ARM     BlackBerry Tablet OS
        default     プラットフォームが指定されていない場合、AIR Debug Launcher(ADL)を使用したシミュレーターでアプリを実行した場合
        -->
        <!-- iPhone用 -->
        <platform name="iPhone-ARM"> 
            <applicationDeployment> 
                <nativeLibrary>libHelloWorldANE.a</nativeLibrary> 
                <initializer>HelloWorldANEExtInitializer</initializer> 
                <finalizer>HelloWorldANEExtFinalizer</finalizer> 
            </applicationDeployment> 
        </platform>
        <!-- iPhoneシミュレーター用 -->
        <platform name="iPhone-x86"> 
            <applicationDeployment> 
                <nativeLibrary>libHelloWorldANE.a</nativeLibrary> 
                <initializer>HelloWorldANEExtInitializer</initializer> 
                <finalizer>HelloWorldANEExtFinalizer</finalizer> 
            </applicationDeployment> 
        </platform>
        <!-- ADL用 -->
        <platform name="default"> 
            <applicationDeployment/> 
        </platform> 
    </platforms> 
</extension>

14. ANEパッケージング

build_ane.bash作る

構文はこれ

adt
-package
-storetype pkcs12 -keystore 証明書ファイル
-target ane ANEファイル名 ネイティブ拡張記述ファイル
-swc ネイティブ拡張ActionScriptライブラリ
-platform プラットフォーム名
-C プラットフォームディレクトリ .

実際これ

#build_ane.bash

adt_directory="/Users/kouseiikeda/Dev/Flash/SDK/flex_sdk_4.6_air_3.4/bin"
root_directory="/Users/kouseiikeda/Dropbox/AIR/Samples/AIR_HelloWorldANE_test/deploy"
extension_xml_path="${root_directory}/extension.xml"
swc_path="${root_directory}/HelloWorldANE.swc"
ane_path="${root_directory}/HelloWorldANE.ane"
${adt_directory}/adt -package -target ane ${ane_path} ${extension_xml_path} -swc ${swc_path} -platform iPhone-ARM -C $root_directory/platform/ios . -platform iPhone-x86 -C $root_directory/platform/iossimulator . -platform default -C $root_directory/platform/default .

ほんとは証明書つけたほうがいいとドキュメントにはあるのだけどオプションなので今回は省略。

問題なければエラー出ずにANEができてるはず。完成。
あとはflaファイル適当に作ってテストすれば、ADL/iOS Simulator/iOSでそれぞれHelloWorldANE.getHelloWorld()から異なる値が取れているはず。

ちゃんとわかってないところ
・extension.xmlの名前空間
・aneビルド時に食わせるswcの役割
・初期化関数の名前のルール

2012.10.04/Development

前のエントリAIR for iOSでiPhone5画面サイズに対応するでiPhone5サイズに対応した。
が、2012/10/4現在ではこのままだと審査に出せない。
AIR SDKは3.5.0.290。次のアップデートではもうこの情報は不要になるとおもうけど。

現象としては

  1. パブリッシュ成功
  2. Waiting for Upload
  3. Application Loaderでアップロード

までは問題なく進むのだがその後

Invalid Launch Image – You app contains a launch image with a size modifier that is only supported for apps built with the iOS 6.0 SDK or later.

というメールが来て、iTunes Connectで確認するとステータスがInvalid Binaryになっている。

意味としては、iPhone5用のサイズの画像が含まれていて、その場合はiOS6かそれ以上でビルドしないといけないが、しかしそうできてないということのよう。

原因としては、現状の最新の安定版であるAIR SDK3.4ではiOS5向けにビルドされていて、その情報がipaの中に含まれているという事。2012/10/4時点でのSDK3.5.0.290でも、だめだった。

解決した。探してみるとフォーラムに同じ現象になったひとがいた。
Build for iPhone5 and AppStore

ここでスタッフ登場。
現時点でBetaであるAIR SDK3.5.0.290でも同様の現象は解消できないのでSDKに含まれるadt.jarを書き換えろと。http://forums.adobe.com/message/4740484#4740484で言ってる。adt.jarも添付してある。
adt.jarのリンクはhttp://forums.adobe.com/servlet/JiveServlet/download/4740484-111267/adt.jar

  1. 上に貼ったリンク、またはフォーラムからjarをダウンロード
  2. 一応、現状のSDK3.5をコピーしてAIR_SDK_3.5_Beta_modifiedADTとか適当に名前をつける
  3. AIR_SDK_3.5_Beta_modifiedADT/lib/adt.jarを上書き
  4. Flash IDEなら「ヘルプ -> AIR SDKを管理」からSDKを追加できるからそこで追加
  5. ターゲットを今追加したSDKを指定
  6. パブリッシュ

これを通常通りApplication Loaderでアップしたところ、冒頭のエラーは出ず、ちゃんとWaiting for Reviewになった
以上解決。

ただもちろん、これは2012/10/4時点、SDK3.5.0.290の話だから、SDK3.5betaの次のリリースでは修正されるだろうし正式リリース時にも勿論修正されるだろうから、とりあえずSDK3.5を落としてやってみて、ダメならこれをやってみる、というのが妥当かと思う。

[ 補足1 ]
他にも色々試していて、
SDK3.4 + platformsdk指定 -> 失敗
SDK3.5 -> 失敗
SDK3.5 + platformsdk指定 -> 失敗
と全滅だった

[ 補足2 ]
ipaに含まれるバージョン情報の話。
“myapp.ipa”をzipとして解凍すると“myapp.app”がでてくる。それで「パッケージの内容を表示」をすると中に“info.plist”があり、そこに“DTPlatformVersion”“DTSDKName”という値があり、そこらへんにバージョン情報が書いてあるよう。
ただ、一度パッケージングしたipaを解凍しそこを書き換えて再度圧縮、とやっても上手く行かなかったみたい。フォーラムの人によると。僕は試してないけど。

普通にAIR3.4でビルドすると、iPhone4Sサイズになる。
つまりiPhone5でアプリを見ると、上下が黒く、サイズが足りていない状態になる。

これは

stage.scaleMode = StageScaleMode.NO_SCALE;
stage.align = StageAlign.TOP_LEFT;
stage.displayState=StageDisplayState.FULL_SCREEN_INTERACTIVE;

をやっても変わらず。

対応としては、スプラッシュ用画像をiPhone5サイズで作成しビルドに含めること。
@sakusan393さんにおしえてもらいました。

具体的には
1136px/640pxの画像を作成し
Default-568h@2x.pngという名前をつけ
ビルドに含める。

そうすると勝手にiPhone5で動かした時に上下の黒帯がなくなります。

ちなみに2012/10/4時点のSDK3.4およびSDK3.5.0.290ではこの後の申請フェーズで失敗する。
それについてはhttp://ikekou.jp/blog/archives/2442