ラベル darkside の投稿を表示しています。 すべての投稿を表示
ラベル darkside の投稿を表示しています。 すべての投稿を表示

2012/02/18

Titanium for Androidでスプラッシュスクリーンを使わない

先日の「Titanium Mobile」で作るiphone/Androidアプリ勉強会で、Titanium for Androidでスプラッシュスクリーンが醜い、なんとかしたい、という話題がでました。で、いろいろ調べてみました。結論は、
1.7.5の場合、<Titanium SDK>/mobilesdk/osx/1.7.5/android/build.py の L.862 にある部分を
<resources>
<style name="Theme.Titanium" parent="android:%s">
<!--
    <item name="android:windowBackground">@drawable/background</item>
    -->
</style>
</resources>
のように書き換えれば、スプラッシュスクリーンが表示されなくなります。
めでたしめでたし。
1.8.xの場合 L.905 あたりに同じ箇所があるので、同様にすれば、いいと思われます。

しかしなんで、こんなところに theme.xml の元データが埋め込まれちゃってるのか ... ぜひとも、外持ちのファイルにしておいてほしいものです。


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が実行されるまでのソースコード追ってみた





2011/08/30

Apple Instruments Automation with Titanium Mobile

Apple謹製のUIテストツール Instruments Automationは、Javascriptで書かれたテストケースを実行してUIテストするツールです。
[iPhone] JavaScriptを使ってUIのデバッグを自動化してみた
[iPhoneプログラミング]iPhone SDK 4からの新機能UI Automationの使い方
などで、Instruments Automationを使用して、XcodeのiOS用プロジェクトをUIテストする例が述べられています。
また、
titanium/UIをテストする(iPhone編)
で、Instruments Automationを使用して、Titanium MobileのプロジェクトをUIテストする例が述べられています。
Instruments Automationは、InterfaceBuilderを使ったプロジェクトを前提としているらしく、シンプルなnon IBのプロジェクトでは、アプリケーションに含まれるUI 要素の名前を使った参照ができないようです。
試しにUI要素の階層構造を取得するために
UIATarget.localTarget().logElementTree();
で、Titanium Mobileプロジェクトの情報を取得してみると、


--logElementTree()
2) UIAApplication [name:Sample value:(null) rect:{{x:0, y:20}, {width:320, height:460}}]
3) UIAWindow [name:(null) value:(null) rect:{{x:0, y:0}, {width:320, height:480}}]
4) UIAStaticText [name:capability value:(null) rect:{{x:20, y:70}, {width:100, height:50}}]
4) UIAStaticText [name:1 value:(null) rect:{{x:135, y:70}, {width:50, height:50}}]
4) UIAStaticText [name:state value:(null) rect:{{x:20, y:170}, {width:100, height:50}}]
4) UIAStaticText [name:0 value:(null) rect:{{x:135, y:170}, {width:50, height:50}}]
4) UIASwitch [name:(null) value:0 rect:{{x:113, y:270}, {width:94, height:27}}]

のように、nameの値が(null)になっているものがあります。
多くの場合、UI要素にtitleプロパティがないもので、nameの値が(null)になるようです。
例えば、Ti.UI.windowならば、titleプロパティを設定すれば、nameによって参照できるようになります。それに対して、Ti.UI.Switchにはtitleプロパティがないようです。そもそもTi.UI.Switchの実体であるUISwitchに該当するプロパティが存在していません。
勢い、nameによる参照をあきらめて、
var switchs = view.switches();
switchs[0].setValue(true);
のように、インデックスによる参照に向かってしまいますが、おそらくこの方式では、Titanium Mobileプロジェクトのコード内で、UI要素をaddする順番を変えたりすると、テストがテストにならない結果になってしまいます。

ではどうすればよいのか?
Instruments AutomationはIBで設定されるAccessibility Labelをnameとして使用しています。non IBのプロジェクトをInstruments Automationでテストするには、テストしたいUI要素に対して、自前でsetAccessibilityLabelを使ってラベルを設定してやる必要がある訳です。


(ここから先は、Titanium Mobile SDKにある元のObjective-Cのソースファイルに手を加える形になりますので、On Your Riskでお願いします)


Ti.UI.Switchを例にとると、Titanium Mobile SDKディレクトリ(/Library/Application Support/Titanium/ か ~/Library/Application Support/Titanium/)以下のmobilesdk/osx/<sdk version>/iphone/Classes内のTiUISwitch.mが対応するソースファイルになります。
@implementation TiUISwitch
@end
の実装部分に以下のメソッドを追加します。


-(void)setTitle_:(id)value
{
UISwitch * ourSwitch = [self switchView];
[ourSwitch setIsAccessibilityElement:YES];
[ourSwitch setAccessibilityLabel:[TiUtils stringValue:value]];
}


これで、Ti.UI.Switchに対して設定可能なtitleプロパティが追加されたことになります。


Titanium側のJavascriptでは、
var sw1 = Ti.UI.createSwitch({
value:false,
title:'testSwitch',


height:'60dp',
width:'150dp',
top:'250dp'
});
のように、titleプロパティの値を追加してcreateするようにします。

これによって、Ti.UI.Switchにもnameをつけることができました。

Ti.UI.Switch以外のUI要素についても同様の追加が可能と思われますので、必要な部分に適宜追加するのがいいと思います。

(TiStudioで既に作成中のプロジェクトについて、上の結果を反映させるには、TiStudioで[project > clean...]でクリーンした上で、プロジェクトパスにあるbuild/iphone/Classes以下のファイルを削除しておくのがよいかもしれません)



UI Automation Reference Collection