# Titanium Mobileの暗黒ノウハウを公開します。
_published: 2011/03/04_ 
WEB+DB PRESS Vol.61の特集は、Titaniumでした。実際にアプリを作りながらのチュートリアルになっています。正統派な入門記事です。
でも。期待してた内容ではありませんでした。私は、Titaniumの暗黒面が知りたいのです。いつものWEB+DB PRESSなら、そんな記事が多いのですが、さすがにまだ開発者が少なそうなTitaniumではアッサリ目に仕上げるしかないのでしょう。そこで、このどうでもいいブログで、Titaniumのバッドノウハウ、いや、暗黒ノウハウをメモっておきます。
アプリを1本開発しただけですので、そこまでTitaniumのことを解っているわけではありません。間違っているところなどがありましたら、指摘してもらえるとありがたいです。暗黒ノウハウをみんなで共有しましょう。あと、スシなどをおごってもらえると、もっとありがたいです。
## 前提。
Titaniumのバージョンは、主に1.5.1です。途中で1.6.0がリリースされたので、状況は変わっているかもしれません。目の前の状況は、刻一刻と変わるものです。現状に甘んじてはいけません。あと、私が作ったのはiPadアプリです。Androidは試してません。
- [TitaniumでiPhoneアプリとAndroidアプリを同時に作ったよ。 - このブログは証明できない。](http://d.hatena.ne.jp/shunsuk/20101203/1291380711)[](http://b.hatena.ne.jp/entry/http://d.hatena.ne.jp/shunsuk/20101203/1291380711)
## 読み方。
Titaniumの読み方ですが、「チタニウム」ではなくて、「タイタニウム」だそうです。オシャレに「タイタニューム」と読んでもいいかもしれませんね。私は「藤岡弘、」と読んでます。
## ビルドできない。
最初に試した頃にTARGET_BUILD_DIRのエラーが出ていました。今は大人になったので、出ていません。もし出たら、プロジェクトの設定をいじると直ります。
- [TitaniumでiPhoneアプリをビルドするとTARGET_BUILD_DIRのエラーが出るとき。 - このブログは証明できない。](http://d.hatena.ne.jp/shunsuk/20101214/1292326102)[](http://b.hatena.ne.jp/entry/http://d.hatena.ne.jp/shunsuk/20101214/1292326102)
最近はまったく再現しないので、私も大人になったんだと思います。
## シミュレーターが起動しない。
エラーが発生したり反応がなくなったりしてシミュレーターが起動しない場合は、再度「Launch」ボタンをクリックしてください。「Launch」が有効で「Stop」が無効になっている場合は、いくら待ってもシミュレーターが起動しないケースが多いです。また、いったん「Stop」して「Launch」しなければならない場合もあります。
私に話しかけても反応が無いときがありますが、再度話しかけると反応します。
## アプリのアイコン。
Titanium Developerでアプリのアイコンのファイル名を変更できます。このとき、存在するファイル名を書く必要があります。むしろ、設定を変えずに、Project/Resources/iphone/appicon.pngファイルを上書きするといいですね。
現在のTitaniumだと、アイコンやDefault.pngがうまく適用されなくて、イライラする日々を過ごすこともあるかもしれません。そんなときは、このサイトを見てください。
- [Nekostagram - ねこ大好き専用Instagram](http://nekostagram.heroku.com/)
## Application IDに使えない文字。
net.shunsuk.MyAppのようなApplication IDには、ハイフンが使えません。ドメイン名にハイフンを使っている人は、残念でした。Objective-Cで作る場合はハイフンもOKなのですが、Androidのパッケージ名で使えないっぽいです。
あと、試してないですが、Application IDには絵文字も使えないかもしれません。
## 使ってはいけないフォルダ名。
公式ドキュメントに載っているのかどうか分かりませんが、使ってはいけないフォルダ名があります。プロジェクトを作ると生成されるResourcesフォルダの下に、contentsフォルダとかresourcesフォルダとかを作ってはいけません。知らんかったら、トラップ以外の何者でもありません。
- [Titaniumでcontentsという名前のフォルダを作ってはいけない罠。 - このブログは証明できない。](http://d.hatena.ne.jp/shunsuk/20110216/1297862770)
システムフォルダの中にエロ画像フォルダを作るのも、相手によっては逆効果だと思います。
## なぜかエラーが起こる。
何の問題もないはずなのに、エラーが起こる場合があります。信じられないかもしれません。私も信じられません。でも本当です。しかも、エラー内容が表示されずに、スタックトレースが表示されます。どうしようもありません。試されてます。この場合は、Project/build/iphoneフォルダ以下をのファイルをすべて削除して、再度実行するとOKです。ちなみに、iphoneフォルダを消すと、デバッグできなくなりますので注意してください。
Titaniumはオープンソースなので、なぜエラーが起こるのか解析して、パッチを送ってあげるといいですね。私もオープンなのですが、心を開いていないと言われることが多いです。
## tiapp.xmlを直接編集。
基本的なことは、Titanium Developerで設定できます。もっと細かい設定をしたければ、プロジェクトのフォルダのtiapp.xmlを編集する必要があります。このへんの設定は、よく使うんじゃないでしょうか。
- statusbar-style
- statusbar-hidden
- orientations
tiappって、なんて読むんでしょうね。血アップ。
## TitaniumはTiと省略可能。
APIの話です。Titaniumは、Tiと省略することができます。なので、下のどちらでもOKです。
- `Titanium.UI.createView();`
- `Ti.UI.createView();`
原子番号22。チタン族元素の一つで、金属光沢を持つ遷移元素です。
## 実機転送。
作ったアプリを実機に転送する場合、Titanium Developerから転送しようとすると下のような手順になります。
- ビルドされる。
- iTunesに登録される。
- iTunesとiPhoneを同期する。
面倒なので、生成されたプロジェクトをXCodeで直接開いて実行する方が速いです。Project/build/iPhoneフォルダにプロジェクトファイルがあります。ただ、そのままでは動かない場合があるので、プロジェクトの設定を適宜変更してください。また、XCodeから実行することで、パフォーマンスツールを利用することもできます。
ビルドにはとても時間がかかります。不要なライブラリを削除すればいい気もしますが、そのへんは調べてません。不要なものを削除していって、結局自分も不要なんじゃないか、という疑問に達した人は、そんなことないよ!!
## AdHocビルド。
AdHocビルドするには、上で書いたように、プロジェクトファイルをXCodeで開いてビルドすると簡単です。プロジェクトにdist.plistなどを追加して、プロジェクトの設定をいじってください。
今日の弁当には、アドホックに玉子焼きがついてました。
## includeの順番。
Objective-Cの#importと根本的に違います。LLのrequireのように、コードが展開されます。この時、includeの順番に注意しましょう。
```js
Ti.include('A.js');
Ti.include('B.js');
```
こう書くと、~~AからBは見えますが、BからAは見えません~~。
追記(2011-03-21):書き間違えてました。BからAは見えますが、AからBは見えません。
includeに関しては、こちらも参考に。
- [TitaniumのインクルードパスをResourcesからの相対パスで指定する方法 | ひげろぐ](http://higelog.brassworks.jp/?p=1130)
今日の弁当のハンバーグには、チーズがインクルードされていました。
## フォントサイズ。
UI部品のフォントサイズを動的に変えたいとき。
```js
textView.font.fontSize = 36;
```
では変りません。font自体を設定します。
```js
textView.font = { fontFamily:'Helvetica Neue', fontSize:36 };
```
フォントにつらくなってきました。
## Objectの生成。
ObjectやArrayを生成するとき。
```js
ver o = new Object()
ver a = new Array()
```
こう書くと、警告が出ます。リテラルを使いましょう。
```js
ver o = {};
ver a = [];
```
これって、JavaScript的な意味があるのでしょうか。そもそも、生きる意味などあるのでしょうか。
## 子Viewのサイズ。
子Viewのサイズを指定していなければ、親Viewの中で最大表示されます。この状態で親Viewのサイズを変えると、連動して子Viewのサイズが変わります。ここで、子Viewのサイズをピクセルで指定していると、連動しなくなるので注意してください。
Titaniumでは、サイズをパーセント指定できます。うまくやれば、マルチプラットフォームに仕上げられますね。でも、なかなか難しいと思うんです。ロジックだけを共有して、UIは切り分けた方がいいと思います。
私の子も、親の私に連動して、背が低いです。
## jQuery。
JavaScriptのライブラリを使えるというのもTitaniumの特徴です。ですが、jQueryはそのままでは動きません。wondowやdocumentなどのオブジェクトがないためです。無理やりjQueryを使うには、こちらの記事を参考にしてください。
- [TitaniumでjQueryを使う | ひげろぐ](http://higelog.brassworks.jp/?p=1148)
ただ、DOMがないので、jQueryを使うメリットがあるのかは微妙です。ちなみに、JQはジェットスター航空の航空会社コードです。紹介したので、サービスしてください。
- [航空券 予約・購入・運賃案内|Jetstar - ジェットスター](http://www.jetstar.com/jp/ja/index.aspx)
## アニメーション。
Titaniumは、アニメーションがやりやすいです。MogSnapというアプリがTitanium製らしいですが、アニメーションが楽しいアプリになっています。
- [もぐもぐエンターテイメント系Twitterクライアント MogSnap ~We Love Mogmog!~](http://mogsnap.jp/)
アニメーションをガンガン使いたいのですが、いろんなタイミングに注意しましょう。例えば、下のコードではmessageWinがcloseするのは500ms後ですので、それまでにmessageWinが閉じられていることを前提としたコードが走るとマズイですね。まあ、これは分かりやすいケースですが。
```js
messageWin.close({opacity:0, duration: 500});
```
私もMogSnapを使っていますが、コンビニおにぎりかマクドナルドかカップ麺なので、使う機会がありません。ちょっと不健康な食生活ですね。健康のため、カップ麺はドラッグストアで買ってます。
## 画像のロードとリロード。
ImageViewは、createImageViewでimageを設定しても、そのタイミングでは画像をロードしません。親Viewにaddしたりして表示されるタイミングで画像をロードします。これは、iOSのUIImageViewと挙動が違うので注意が必要です。
また、ImageViewがremoveされても、すぐに画像がリリースされません。キャッシュしてるっぽいですが、詳しくは調べていません。そのImageViewを使う予定がなければ、サイズの小さい画像をimageにセットすることでメモリを節約しています。ホントはやり方があるかもしれませんが。
メモリ管理の必要がないところが、メリットでもあり、デメリットでもありますね。記憶を管理して、黒歴史を消し去りたいですね。マインドアサシン。
## ScrollViewの謎挙動。
ScrollViewにImageViewを乗せて画像をズームします。ズームした状態で、関係ないWindowを開きます。そして、Windowを閉じます。すると、ScrollView上のImageViewの位置がおかしくなるという謎挙動に遭遇しました。今のところ、原因不明です。
私もよく、原因不明の物欲に駆られて、原因不明のアマゾンで、原因不明の買い物をします。
## クロージャ。
クロージャを使わないと、思ったように動作しないケースがあります。ファイルを分割して、コンテキストが別になった場合などで必要になるんでしょうか。知らんけど。クロージャに慣れていない人は、復習しておいたほうがいいかもしれません。
```js
var label = Ti.[UI](http://d.hatena.ne.jp/keyword/UI).createLabel();
view.layout = (function() {
var l = label;
return function(message) {
l.text = message;
};
})();
```
そんなに、くろーじゃないよ。って言いたかっただけです。
## ちょっと。
コードスニペットを。イマイチなのも公開しときます。
デバッグするときにTi.API.info("デバッグ!")と書くのが面倒なので、utility.js的なファイルに下のコードを書いてapp.jsの先頭でincludeしておきます。
```js
var info = Ti.API.info;
```
そうすると、こう書けます。
```js
info("デバッグ!");
```
完璧グローバルですが、この場合はいいんじゃないかと思います。
clickイベントをハンドルする場合、こう書きます。
```js
button.addEventListener('click', function(e) {
info("clicked");
});
```
これも、utility.jsにこう書いておくと。
```js
Object.prototype.click = function(handler) {
var sender = this;
this.addEventListener('click', function(e) {
handler(sender, e);
});
};
```
こう書けるようになります。
```js
button.click(function(sender, e) {
info("clicked");
});
```
完全に好みの問題なので、なにか便利になるわけではありません。Object.prototyeを汚染してますし、senderなんてなくてもe.sourceでOKですし、いろいろ腑に落ちないところはあります。でも、button.clickって書きたいんです。おすすめじゃないですが、いちおう書いておきました。
最後に、これもutility.jsに書いておきます。
```js
var getImageFile = function(name) {
return Ti.Filesystem.getFile(Ti.Filesystem.resourcesDirectory, 'images/' + name);
};
```
そうすると、imagesフォルダに入ってる画像を短いコードで呼び出せます。
```js
imageView.image = getImageFile('profile.png');
```
## フレームワーク。
JavaScriptでAIRアプリを作った時も思ったのですが、画面遷移まわりなど、薄いフレームワークを作ったほうがよさそうです。ガチガチのフレームワークは必要ないのですが、JavaScriptは柔軟性が高い分、統制がとれなくなる可能性が高いので。
まあ、柔軟性が低い上に統制もとれてない私に比べれば、たいした問題ではありません。
役に立つかどうかわかりませんが、いろいろ書いてみました。「間違っているところがあるかもしれません」と書いて逃げるのは好きではないのですが、間違っているところがあるかもしれませんのでご注意ください。
たくさん書いたので、スシが食べたいです。