2011/09/06

Titanium:jsはどこに行った iOS編

app.jpなどTitanium Mobile のJavascriptのソースファイルが、ビルド後どう処理されるのか、どう実行されるのか、気になるところです。
調べてみると、iOS用の場合、シミュレータ用とそれ以外のビルドの場合取り扱いが違っていることがわかりました。前者と後者とでは、ApplicationRouting.mの内容が異なっています。


実機テスト用および配布用ビルドのApplicationRouting.m
@implementation ApplicationRouting
+ (NSData*) resolveAppAsset:(NSString*)path;
{
     static NSMutableDictionary *map;
     if (map==nil)
     {
         map = [[NSMutableDictionary alloc] init];
         [map setObject:dataWithHexString(@"54692e55492e7365744261636b677...... 中略 ....e28293b") forKey:@"app_js"];
     }
     return [map objectForKey:path];
}


@end
シミュレーション用ビルドのApplicationRouting.m
@implementation ApplicationRouting
+ (NSData*) resolveAppAsset:(NSString*)path;
{
    return nil;
}


@end
実機用配布用の場合には"app_js"をキーとしてバイトコードもどきのデータが生成されていますが、シミュレーション用の場合には、マップ自体生成されないコードになっています
resolveAppAssetを呼び出している箇所TiUtils::loadAppResourceを見てみると、シミュレーション用の場合には、直接プロジェクトディレクトリのResources内のjsファイルを読んでいることがわかります。Objective-Cのファイルをビルドなしで素早くJavascriptの修正を反映させるために、この方式が採用されているようです。

さて、読み取られたJavascriptは、KrollBridge::evalFileOnThreadで実行されることになります。先ほどのバイトコードもどきの文字列は、実はUTF8 ストリングエンコードされただけのJavascriptそのものだとわかります。いけないことを思いつきそうなので今日はこれくらいにしておきます。


----------------------------------追記----------------------------------
「シミュレーション用の場合には、マップ自体生成されないコードになっています」とかきましたが、その後、いろいろなケースで確認すると、正しくは「モジュールを追加していないプロジェクトでシミュレーション用のビルドをした場合に限り、マップ自体生成されないコードになる」でした。


なぜ、モジュールの追加との依存関係があるのかは、今のところ謎ですが、思い当たる現象はいくつかあります。確認できたらまた報告したいと思います。

先行事例
Titanium MobileでJavaScriptが実行されるまでのソースコード追ってみた





0 件のコメント:

コメントを投稿