どうしてTitanium Mobileなの?
ウェブ開発者がiOSやAndroid向けアプリを作ろうと思い立った場合、今なら大きく分けて2つの選択肢があります。ひとつは他の人たちと同じようにObjective-CやJavaで素直にアプリを作ることです。まあ、当たり前ですね。もうひとつの方は、PhoneGapやTitanium Mobileのようなサードパーティーのツールを利用してJavascriptなどウェブ開発者の慣れ親しんだ言語で開発するやり方です。それぞれ一長一短があります。先のやり方では、ネイティブな開発用言語だけあって全ての機能を最大限に活かすことができます。AppleやGoogleも最大限の開発支援を提供してくれることでしょう。しかし、Objective-CやJavaに慣れ親しんでいた人でなければ学習曲線がなかなか上昇してくれないかもしれません。特にウェブ開発者はWebObjectsをやっていた人でもない限りはObjective-Cに馴染みの無い人が多いでしょう。また、ヘッダファイルを書くことやDelegateみたいなまだるっこしいデザインに疲れてしまうかもしれません。そんな場合、サードパーティーのツールで素早く開発しながら徐々に慣れていく方が安全なやり方といえます。一方で、サードパーティーのツールには最上位のベンダつまりAppleやGoogleの意向でいつ排除されてしまうかわからないというリスクもあります。これまで見たところでは、今年や来年にそんなことが起きるとは到底考えられないのですが、それでも細かいトラブルはあるでしょう。
以上のような状況を鑑みるに、もしあなたがObjective-CやJavaでの開発に不安が残る状態であるなら、迷わず後者の方を選択するべきでしょう。その上で、自分の開発しているプラットフォームについて知ることは重要であり、そうであればいずれはネイティブな言語での理解が必須になるでしょうから、得られる知見を最大限に活かしてObjective-CやJavaでの開発について学んでいくのが理想です。例えば、PHPを使って開発をしていても、それだけしか知ろうとせず、ウェブサーバやPHP自体の実装といった抽象化されて隠された部分に分け入って進もうとしない人が、筆者の経験ではありますが、競争に耐えうる優秀な人材であった試しはありません。幸いにもサードパーティーのツールにはソースコードにアクセスできるものもあるので、良い手本になることがたくさん見つかるでしょう。
では、数あるサードパーティーのツールの中で、一体どれを選べばいいのでしょうか。
もちろん、おみくじで決めたとしても、それは当人の責任の範疇ですから、全く構いません。しかし、それでもやはり、いくらなんでももう少し真面目に考えないと不安になるかもしれません。なので、そうですね、それぞれのツールの特徴を掴んだ上で判断する方がいいでしょう。私自身も決定的な答えを用意しているわけではないので、知っている範囲で自分の意見を述べたいと思います。情報は最新とは限りませんので、ここは違う、いや今はこうなっている、などなどご意見あれば是非聞かせてください。いずれにせよ、現段階ではちょっとした宗派の争いみたいになりがちな話題なので、リラックスしてお読みくださいね。
サードパーティーのツール、と上ではひとくくりにしましたが、大きく分けるとこれも二種類に分かれます。ひとつはPhoneGapやRhodesのようにHTMLとJavaScriptで作ったUIをWebView(UIWebView)を使って表示させる、ウェブアプリとネイティブアプリが合体したようなもの、もうひとつはTitanium MobileのようにネイティブなAPIを叩いてJavascriptで記述しながらネイティブアプリとして動作するものです。ここでは実際に使ったことのあるPhoneGapとTitanium Mobileを比較します。
私見では、PhoneGapのいいところは第一にそれがシンプルであることです。例えば生成されるJavaのクラスは非常にシンプルで、実際に使ってみたところカスタマイズも容易でした。APIも数えるほどしかなく、プラグインの作成もそれほど難しいものではありません。また、UIはHTMLとJavascriptで作るので、ウェブ開発者やデザイナのこれまでに培った技術を活用することができそうです。
それに、例えばFacebookアプリは現在PC向けのものはHTMLで作られていますが、モバイル向けも今後は同じくHTML5を利用して記述され、Facebookのモバイル用アプリ内で動作するといったものになっていくことが予想されます。クロスプラットフォームでの開発が容易なのはHTMLの強みですから、こうした流れにソーシャルゲームのプラットフォームも追随していくのではないかと思います。
しかし、欠点もないわけではありません。jQuery MobileやSencha Touchといったツールを使ってなるべくネイティブアプリに似せることは出来ますが、それでもUIはネイティブなものではありません。これらのツールキットはまだ開発されてから日も浅くベストプラクティスも少ないので、開発はお世辞にも快適とはいえないのですが、それなのに特にiOSではHTMLとCSSででっち上げた「ネイティブっぽい」UIの「偽物」っぽさが際立ちます。動作もまだまだ快適とはいえません。またネイティブな機能への橋渡しをしてくれるAPIも豊富とは言い難いので、少しでも複雑なことに挑戦すると結局Objective-CやJavaでプログラムを作成する必要が生じます。UIレベルの話ならまだしも、例えばiCloudへの対応といった要求にはツール側での対応を待つかそれなりの工数を費やしてプラグインを作成することになってしまうでしょう。それに、これは年月が解消してくれる問題なのかもしれませんが、例えばSnapdoragonの第1世代のIS03のような貧弱なハードウェアではWebViewのようなリソースを消費するものはどうしても動作が遅くなります。オリエンテーションの変更の際にレイアウトが酷く崩れるといったユーザに不安を与えるような現象が発生することもあります。
最近、PhoneGapの開発元がAdobeに買収されることが発表されましたが、資金的には大きな後ろ盾を得たと同時に、大企業であり、これまで数々のプロダクトをディスコンにしてきたAdobeにその命運を握られてしまったともいえます。
以上、駆け足ですが個人的に思うところを述べてみました。先ほども書きました通り、ここは違う、いや現在はこうなっているといったご意見などございましたらお知らせください。
さて、その一方でTitanium Mobileの場合、Javascriptで記述した内容は評価された後にプロキシを通じてiOSやAndroidのAPIに渡されて実行されるため、実際に動作するのは通常のアプリと同じものなので外観は全くネイティブなアプリと変わりません。と同時に、Titanium.UI.WebViewというものが用意されているので、やろうと思えばHTMLとJSでUIを作ってしまうことも可能です。またこのJSとネイティブな機能を繋ぐのも非常に容易なので、この点でも大きなアドバンテージがあります。動作速度はネイティブアプリと比較すれば、インタプリタとコンパイル言語ほどではなくても、まあある程度の差はあります。しかし、シビアな反応が求められるゲームや電子書籍リーダといった特定用途のアプリでなければ実際に問題になるほどではありません。ネットワーク越しにデータをやり取りするアプリ、ウェブサービスのフロントエンド用アプリとして利用するには十分といえます。それに、驚くべきことに、最近ではQuickTiGame2dのような高速で動作するゲームエンジンも開発されていますので、ゲームの開発に利用されるようになる日も近いでしょう。また、このようなサードパーティーのモジュール開発も盛んで、Open Mobile Marketplaceで有料、無料を問わずたくさんの機能拡張用モジュールが公開されています。Githubにソースコードが公開されているものも少なくありません。
それから、jQuery MobileやSencha Touch(Ext.JS)といった一種独特なJavascriptよりも、commonJSといったモダンなJavascriptで記述することが推奨されているのもポイントです。最近ではNode.jsのようなサーバサイドのJavascriptもありますが、Titanium MobileのJavascriptもCoffeeScriptやcommonJSのような今時の技術を習得する近道となるでしょう。というのも、Titanium Mobileは基本的にはよくあるイベント駆動型のGUIのプログラミングなので、Node.jsのようなコールバックにつぐコールバックの連続にも面食らうことはありません。
と、いいことばかり並べましたが、もちろん問題もないわけではありません。Aptanaを買収してEclipseベースの独自のIDEがリリースされましたが、Eclipseがそうであるように人によってはあまり快適とはいえないものです。もちろん使わないで開発することも可能ですが、最初はやはり公式なツールを使いたくなる方も多いでしょうから、そこら辺で面食らうこともあるかもしれません。またビルドスクリプト内部にビルドにかかる時間短縮のため高速化する工夫があるのですが、何度も繰り返してビルドするうちにそれが邪魔をしてアプリの挙動がおかしくなることがありますので、ときどきCleanしてあげる必要があるといった癖のあるところも見受けられます。また海外製品にありがちなことですが、Pythonを使ったビルドスクリプトはUTF-8のMac OS Xで日本語の処理に問題がある箇所が多数ありますのでアプリ名称やプロジェクト名、ソースコードのフルパスに日本語が含まれていると辛い目に遭います。その辺りは、日本語でも有志によるサポートコミュニティがありますので、活用してください。
これらは今後改善されるべきことではありますが、一方で大半は公開されたソースコードから追いかけることも可能なことであり、ついでにいえばパッチを送って直してしまうことだって出来ます。個人的には、いつか大金持ちになって暇を持て余すようになったら、面倒の多いPythonの部分を全部Rubyにしてしまいたいと思っています。また、Titanium Mobileを入り口としていろいろと学びましたが、逆にネイティブな言語で開発しなくてもいいやという気にもなってきました。やっぱりDelegateとかってうんざりますよね?
以上、駆け足で比較していきましたので粗雑な部分、間違いなどもあるかもしれません。上にも何回か申し上げましたように、これは違うぞ、といったところがあればどしどしご指摘ください。よろしくお願いします。
Popularity: 7% [?]
Titanium、みんなどうやって書いてる?
Titanium Mobileでアプリを作るとき、みなさんはどうやって書いてますか?最近のプログラム開発なら、オブジェクト指向的な書き方であったりMVCなどいろいろなやり方があるでしょうが、TitaniumでJavaScriptだけで書いていると、どうもそれらとはあんまり親和性が高くないな、と気になっています。
自分はどうかといえば、例えば下のようにごく普通の書き方をしています。
//便利関数群
var utils = require('utils').utils;
var style = require('style').style;
var db = require('db').db;
//お約束
Titanium.UI.setBackgroundColor('#000');
var tabGroup = Titanium.UI.createTabGroup();
//初期化処理
db.init();
//rootウィンドウでも作りましょうか
var win = Titanium.UI.createWindow(style.top_win);
var tab1 = Titanium.UI.createTab(style.top_tab(win));
//rootウィンドウを表示しましょう
tabGroup.addTab(tab1);
tabGroup.open(style.open_tab);
そんなに大きな特徴はないですが、強いて挙げれば、viewの作成時のパラメータはHTMLとCSSみたいな関係にしてロジックとは分離したいので、style.jsというファイルを別に用意して、そちらに置くことで後で楽になるようにしています。i18nの絡みで文言などもこちらに移しています。
例えばこんな感じ。
var style = {
top_win:{
title:L('howdy'),
backgroundColor:'#fcf',
barColor:'#000'
},
top_tab:function(win){
return {
window:win,
title:L('pow pow pow')
};
},
open_tab:{
transition:Titanium.UI.iPhone.AnimationStyle.FLIP_FROM_LEFT
}
};
exports = {style:style};
わかりやすいし、別に問題はないのですが、美しくはありません。例えば「便利関数群」となっているところなんかは、もっときれいになるはずです。
が、どうもまだこれといったやり方が思いつきません。皆さんはどんな感じでやってますか?
Popularity: 2% [?]
TitaniumのHTTPClient
TitaniumでTitanium.Network.createHTTPClientをネストさせて使おうとするとうまくいかない。
var url = 'http://example.com/a';
var http = Ti.Network.createHTTPClient();
http.onload = function(){
var url2 = this.responseText;
var http2 = Ti.Network.createHTTPClient();
http2.onload = function(){
//素敵なサムシング
};
http2.open('GET, url2);
http2.send();
};
http.open('GET', url);
http.send();
詳しく調べていないが、なんとなく試してみたら下のようにするとうまく動作する。
function http_client_two(url){
var http = Ti.Network.createHTTPClient();
http.onload = function(){
//素敵なサムシング
};
http.open('GET', url);
http.send();
}
function http_client_one(){
var url = 'http://example.com/a';
var http = Ti.Network.createHTTPClient();
http.onload = function(){
var url2 = this.responseText;
http_client_two(url2);
};
http.open('GET', url);
http.send();
}
http_client_one();
こんな感じでネストするHTTPクライアントを関数として外に出す。とりあえずのメモ。
Popularity: 2% [?]
Titanium DeveloperでAndroid(5)
今まで見つけた、Androidの場合に起きる不具合について。
(1) httpClientでPOSTリクエストが送れない、外部とのsocket通信ができない
これは笑っちゃうようなレベルの不具合で、よくもまあリリースしたもんだと飽きれる。HTTPによる非同期通信を起動しても、POSTリクエストで値を送信することができない。じゃあsocket通信でなんとかしようと気合いを入れ直すと、実はAndroidではsocket通信も動作しない。
対応方法は、GETまたはリクエストヘッダに細工してデータを送るくらいしかない。次期リリースで改善されるという噂だが、どうだろう。正直まだあまり信用できない。
(2) 暗黙のIntentで適切なメディア再生用アプリケーションが起動できない
Intentで直接メディアプレーヤーやPDFビューワを起動したくても、いったんブラウザが起動してからブラウザ経由で呼ばれてしまう。
対処方法としては、AndroidManifest.xmlにIntentFilterを記述してやればいいようだが、時間がなかったのでIntentを作成している箇所をいじってTitanium mobileの機能を拡張した。ちょうどここにやり方が出ていたのでこれをヒントにやってみたらうまくいった。
(3) MediaPlayerがサーバ上のデータにアクセスできない
驚いたことに、KitchenSinkからリモートサーバのメディアへのアクセスがAndroid版から削除されていた。これはどうしようもないので、(2)と同じようにTitanium mobile側を改造するか、諦めるしかない。
というのも、例えばUIWebViewでHTML5のvideoタグを使ってメディアプレーヤの代用としてみても、Androidではアプリ内から起動するwebviewではvideoタグは起動しない仕様なので、いくら頑張っても無駄になる。
ただし、(2)の方法を使うと、openURLの改造でIntentが思い通りに動くようになるので、その場合はTitanium.Platform.openURL(またはそれを拡張した関数)でリモートのURLを呼び出してしまえばいい。メディア再生用の別アプリケーションが立ち上がるが、iPhoneと違ってAndroidなら再生が完了したらまた自分のアプリに画面が戻る。
(4) orientationの制限がまともに動作しない
これはAndroidManifest.xmlをいじって対応できる。まあ、魔術としかいいようがないが。
これらはいずれもiPhoneでは正常動作しているものが、Androidに限って動かないケース。繰り返しになるが、よくまあリリースしたもんだ。
Popularity: 4% [?]
Titanium DeveloperでAndroid(2)
前回まででSDKの用意ができたので、今度はサンプルを動かしてみよう。Titanium mobileには開発元のAppceleratorが公開してくれている「Kithchen Sink」というサンプルがあり、githubから入手できるので、さっそくインポート。失敗したら、新規にプロジェクトを作成してファイルをコピー(とチュートリアルに書いてある)。
ではエミュレータを起動、ほらすごい!といいたいところだが、なんとこのサンプルが、動かないのである。困ったものだ。原因はいろいろあるのだろうが、そもそもエミュレータで起動しない。もうどうしようもないので諦めるしかない。ちなみにiPhoneではちゃんと動く。 update: 動くようになった。
Androidに関してはKitchen Sinkはクソの役にも立たないわけだが、これでTitanium mobileのAndroid向け開発の能力には多いに疑念が湧いたため、シンプルなプロジェクトを新規に作成してサンプルにある各機能を試してみたが、全く先に進まない機能もある。でも試行錯誤するうちに、そんなときには、たまに何かわからないことがあったら、AndroidのSDKからこんなツールを起動してみるといいことがわかった。
Dalvik Debug Monitor
これは起動中のエミュレータをアタッチしてログ情報を表示してくれる便利ツールで、Android SDKのtools/ddmsという名前で格納されている。ちなみにマルチモニタに対応していないため、MacBookなどで主画面以外で起動するとクラッシュするので要注意。
もちろん、それでもダメなものはダメだ。例えば、ビデオのストリーミング再生はどう頑張っても音声しか出てこない。エラーをみるとバッファの取得中にタイムアウトしているようだが、だからなんだというのか。困ったものだ。
Popularity: 3% [?]
Titanium DeveloperでAndroid(1)
Mac OS Xでの作業を記録。
まず何より先にAndroid SDKを入手。brew からでもいいが、なんとなく、あくまでもなんとなく、ダウンロードして$HOME直下に設置。
設置したら、今度は各プラットフォーム向けコンポーネントをインストールする必要がある。ターミナルから$HOME/android-sdk-mac_86/tools/androidを起動する。

「Available packages」からAndroid Repositoryを選択して、とりあえず全部一気にインストール。
ここでちょっとした作業が必要になる。android-adk-mac_86/platform-tools以下にadbというスクリプトがあるのだけれど、これはSDKのバージョン7まではtools以下にあったらしい。Titanium Developerの作成するビルドスクリプトではまだtools以下にadbがあるものと見なしているらしく、このままではSDKの登録がエラーになってしまう。
とりあえず、手っ取り早く
ln -s $HOME/android-sdk-mac_86/platform-tools/adb $HOME/android-sdk-mac_86/tools/adb
で対処する。
update: このとき、Third party Add-onsからGoogleのレポジトリを選択して、そちらからのデータの取り込みもやっておく。地図APIなど必要なクラスライブラリがないのでデモ用のアプリケーションが動作しないのだ。

Popularity: 1% [?]
Peclのspidermonkey
jsが入っているのにJavascriptのインタプリタ以外に使い道がないなあ、と思っていたらPeclにspidermonkeyというのが追加されていた。検索するともう記事が見つかったりして、楽しそうなのでさっそくインストール。PHP5.3beta0以上が必要なので、テスト環境のPHPもついでに更新。php.iniのextension_dirを
extension_dir=/usr/lib/php/exntesions/no-debug-non-zts-20090115
のように更新しておかないといけない。
で、pecl install spidermonkey-alphaを実行したら見事にこける。ヘッダファイルjsapi.hがないとのこと。でもそのファイルは/usr/include/直下にある。で、手動でspidermonkey拡張モジュールをダウンロードしてconfigureの中身を見ると、
for i in $PHP_SPIDERMONKEY /usr/local /usr; do
for j in js mozjs; do
test -f $i/include/$j/jsapi.h && SPIDERMONKEY_BASEDIR=$i
&& SPIDERMONKEY_INCDIR=$i/include/$j && SPIDERMONKEY_LIBNAME=$j
&& break
done
test -f $i/include/$j/jsapi.h && break
done
if test -z "$SPIDERMONKEY_INCDIR"; then
{ { echo "$as_me:$LINENO: error: jsapi.h not found. Please reinstall libjs." >&5
echo "$as_me: error: jsapi.h not found. Please reinstall libjs." >&2;}
{ (exit 1); exit 1; }; }
fi
こんな箇所があり、spidermonkeyのヘッダファイルは/usr/includeか/usr/local/include直下ではなくその下のjsかmozjsディレクトリでないといけないらしい。なんなんだ。以前spidermonkeyをインストールしたときの手順に問題があるんだろうか。
まあ、ヘッダファイルはみんなjs*.hという名前だったので、さくっと
# mkdir /usr/include/js && cd /usr/include/js # for i in `ls ../js*.h`; do ln -s $i `echo $i | sed "s/..\///"`; done # pecl install spidermonkey-alpha
適当なことをやって、ようやくインストール完了。ちなみにmozjsにするとやっぱりpeclからのインストールは出来なかった。なぜだ?
Popularity: 3% [?]
IE7だと誤ったフォーマットのRGB色指定はエラー
Internet Explorer 7で下のJavascriptを実行するとエラーになるのね。
<span id="here" style="color:#000000">hoge</span>
<script>
document.getElementById("here").style.color = '#0000000';
</script>
Popularity: 2% [?]
くらえiPhone!
iPhoneでアクセスしてきたら、とりあえず先に90度回転しておいて、縦にしても横にしてもずっと画面が傾いたままにしてしまえばいい。(参照)
Safariでアクセスして動いてたからたぶんこれで大丈夫だ。
iPhone専用ページ
update: 実機を借りたので試してみたらだめだった。畜生め。
update2: いちおう動いていた。
update3: くそっ!Windowの幅や高さが変わったら回転するというのはできなかった。画面をフリップさせてもwindow.outerWidthやwindow.outerHeightの値は変わらないらしい。
function flipYou(){
document.body.style['-webkit-transform']='rotate(90deg)';
height = window.outerHeight;
base = 90;
setInterval(function(){
if(height != window,outerHeight){
base += 90;
com = 'rotate(' + base + 'deg)';
document.body.style['-webkit-transform']=com;
height = window.outerHeight;
}
}, 5000);
}
これではちゃんと検知しない。heightをwidthにしてもダメ。
Popularity: 1% [?]
クッキーモンスター
ファイル名や変数名にはみんないろいろこだわりがあると思うが、同好の士を見つけるとうれしくなる。
live365.comのプレイリスト表示ページのソースだが、クッキーを扱うらしきJavaScriptの名前に驚いた。3年くらい前から、仕事でもクッキーの名前の一部や何かのキー、関数名、変数名に自分でもこの名前を使っていたので。
Popularity: 1% [?]

