uirouのひとりごと

不定期に何か書こうと思います。

titanium STUDIO 1.0 を使ってみた

土日に時間ができたので、いじってみたかった Titanium Mobile なるものをいじってみようということで、いじってみましたよの日記。

Titanium Mobile とは

Titanium Mobile は、

というステキ開発ツールらしいデス。ということで興味を持った次第。

今回の目標

  • iOS シミュレータで動く
  • iOS 実機で動く
  • KitchinShink? を動かしてみる
  • Android シミュレータで動く
  • 外部のWebPageを叩いて何かを表示してみる
  • EVE Online のスキルトレーニングが終わるまでの時間を表示

以下、忘れないうちのメモ。
とりあえず iOS で動かしたかったので Mac で作業しています。

Titanium Developper は古い

どうやらついこの間の 6月14日に titanium STUDIO 1.0 なるものがリリースされたらしい
それと同時に今までの Titanium Developper なるものは開発が停止したんだそうな。
ということで、これからは titanium STUDIO を使うといいらしい。
というあたりで困ったのは、google先生の教えてくれる情報はだいたいが Titanium Developper の話で、titanium STUDIO については当てはまらないものが多いということだった。ガビーン

んでまぁ、とりあえず手持ちのスマートフォンというか、持ち運べるデバイスiOS だけなものだから、Andoroid は後回しにして iOS だけで良いので作ろうとしてみる方向で。

iOS の開発キットを入れる

これはまぁ、しばらく使っていなかったので古くなっていた Xcode とかを
iOS Dev Center
あたりから持ってくることにした。なにやら長い間放置していたため、「らいせんすあぐりーめんとが変わったよ」というのがその Dev Center ページの上の方に出ているのに気づかなくて「ダウンロードできねぇーなんでだー」とかしばらく悩んだのはナイショ!

んで、当然のように私の iPhone にいれていた Provisioning は失効していたので、もう新しい Provisioning を作ってやることに。これは昔と比べるとスゲェ楽になってるのね。

iOS Provisioning Portal

なるところで Launch Assistant ってのを選んで言われるとおりにしてたら全部できちゃって楽チン。だった。:D

git を入れる

どうやら titanium STUDIO は git に対応してるんだぜ、とか言っていたので、git を入れた。

http://code.google.com/p/git-osx-installer/

から拾ってきてそのまま突っ込んだだけ。

titanium STUDIO を入れる

http://www.appcelerator.com/products/download/

から Community ってのを拾ってきていれてみることにする。どうやら Community の奴だと実機でのデバッグができないっぽいけれど、きっと deploy はできるのだろうからということで Community にした。

インストール自体は簡単に終わって、試しにひとつ作ってみることにした。

Titanium Mobile Project ってのを選ばないと iOS では動かないらしいのでとりあえずそれを選んでみて、普通に iOS のシミュレータで動くことを確認。簡単だなぁ。


(Mobile Project を選ぶ)

で、どうやら titanium STUDIO は Eclipse をもとにしているらしいので、きっと emacs key binding もできるんじゃないかなと調べてみるとどうやら

Titanium STUDIO → Prefernce → General → Keys → Scheme

で、Emacs が選べるっぽい。やったね!
ついでに、

General → Editors → Text Editors

で、 Show line numbers にチェックを入れたりした。まぁこのあたりはテキトーに設定するのがいいのではないでしょうか。見たところほんとに Eclipse と同じっぽいし。

実機に転送してみる

シミュレータで動くのはわかったのだけれど、実機に持っていけないのではあまり面白みが無い、ということで、実機に持っていこうとしてみる。
で、ここで躓いてしまったのだけれど、どうやら titanium STUDIO の前の Titanium Developper ってのだとRun on Device なるタブがあって、そこで設定ができるらしいのだけれど、titanium STUDIO には見たところそのようなタブはない。

うーむむむ。google先生 は titanium STUDIO についてはあまりよく知らないらしく、教えてくれないのでテキトーにいろいろいじってみることに。

で、いろいろいじっていて、Project Explorer ってところの 右向きの三角が囲われている ような何か(再生ボタンっぽい何か)のドロップダウンリストっぽい所を押すと、iOS Device ってのが選べて、それを選ぶと Provisioning Profile が指定されていないヨという事でダイアログがでて、それらしい設定ができた。ということで、先ほど作った Provisioning Profile を upload させて、実行してみると、単に iTunes で実機に転送されて終わり……


(再生ボタンっぽい何かのあたりを押すと、iOS Device に転送できた。やり方的にはこれでいいのかなぁ。)

な、なるほど。実機でのデバッグはできないというのはそういうことか!

まぁ、いいや。iOS シミュレータは遅くないし。

KichenSink を動かしてみる

それでは、どんなことができるのかを知りたいなぁということで、Titanium Mobile でできることは全部入っているんだぜとかどこかで聞いた KichenSink ってのを動かしてみることにする。

KichenSink は GitHub で公開されているのでそのままダウンロードしてきて展開。
titanium STUDIO で Import Project → Titanium → Import Existing Titanium Project を選んで KichenSink が展開されたフォルダを指定することで import は完了。

なにやら Android SDK がないから嫌だとか、iOS のバージョンが 3.2 でないから云々、とか言っていたのはとりあえず無視することにする。

で、import したら普通に動いた。何故か iOS シミュレータと Andoroid シミュレータしか選べなくて実機には転送できないっぽい。なんでだ……

と、思ったら、一度ビルドした後に先ほどの再生ボタンっぽいもののドロップダウンリストをだしてみると iOS Device が出てきた。どういうことだ……

で、iOS Device を選んでみると、ビルドで失敗する。

[ERROR] xcodebuild: error: The directory /Users/limura/Desktop/TitaniumMobile/appcelerator-KitchenSink-0b4fd5d/build/iphone contains 2 projects, including multiple projects with the current extension (.xcodeproj). Specify the project to use with the -project option.
[ERROR]
[ERROR] Error: Traceback (most recent call last):
File "/Library/Application Support/Titanium/mobilesdk/osx/1.7.1/iphone/builder.py", line 1296, in main
execute_xcode("iphoneos%s" % iphone_version,args,False)
File "/Library/Application Support/Titanium/mobilesdk/osx/1.7.1/iphone/builder.py", line 1057, in execute_xcode
output = run.run(args,False,False,o)
File "/Library/Application Support/Titanium/mobilesdk/osx/1.7.1/iphone/run.py", line 39, in run
sys.exit(rc)
SystemExit: 78

だそうだ。ふむー? なにやらバージョンが違うから云々、と言っていたのはコレかな、と思い込んで、みなかったことにする。:P

Android SDK でもビルドできるようにしてみる

そろそろ Android でも動くようにしてみたくなってきたので、ビルドできるように設定をしてみる。

まず、

http://developer.android.com/sdk/index.html

から Mac用 の Android SDK を download してきた。

……で、これを展開した後に出てきたものをどうやって titanium STUDIO に認識させればいいのだろう?ということで、Google先生に聞いてみると

http://wiki.appcelerator.org/display/tis/Installing+the+ADT+Plugin

というお告げをうけたのでそのままこのページの言うとおりに Java とか Android ADKプラグインを titanium STUDIO に入れた。

ということで、

TitaniumStudio → Preferences → Aptena → Titanium

Android の項目で Android SDK Directory をダウンロードしてきた Android SDK のフォルダを指定してみたのだけれえど Default Android SDK の所にバージョン番号がでない。どういうこと?

と思っていろいろ調べていると、どうやら Android SDK はダウンロードして展開しただけでは駄目で、展開した後にできる tools\android を動かして、Available packages から目的の SDK を入れてやらないとイケナイのねこれ。はっはっはー。気づかなかったよ!


(Android SDK のうち望みのものをインストールする)

で、SDKのダウンロードが終わったら、titanium STUDIO側の

TitaniumStudio → Preferences → Aptena → Titanium

で出てくる Android の項目にSDKのroot directoryを指定したらちゃんとSDKを選べるようになった。よしよし。

と、いうことは?もしかして

http://wiki.appcelerator.org/display/tis/Installing+the+ADT+Plugin

についてはやらなくてもよかったのかもしれづ。

まぁ、Android でのシミュレータが動いたし、よしよし、ということにする。


(Android のシミュレータでも動いた)

外部のWebPageかなにかを叩いて何かを表示してみる

さて、ここまでで基本的な事まではできたので、sourceを書き換えていろいろしてみることにする。

とりあえず、

http://code.google.com/p/titanium-mobile-doc-ja/wiki/get_started

を参考にして開始。(この情報はどうやら Titanium Developper 用に書かれているっぽいので、モノによっては変な情報になってたりするみたいなのは注意デス)

app.js 以外のファイルを使う

http://code.google.com/p/titanium-mobile-doc-ja/wiki/get_started#app.jsからWindow単位のスクリプト分離

によると、どうやら

var win1 = Titanium.UI.createWindow({
title:'Tab 1',
backgroundColor:'#fff'
});

と書いてあるようなところを

var win1 = Titanium.UI.createWindow({
title:'Tab 1',
backgroundColor:'#fff',
url: 'win1.js'
});

としてやる(url: 'win1.js' というあたりが追加されている)と、このウィンドウについては win1.js の中身が実行される、ということらしい。

どれどれ? ということで、とりあえず Resources/iphone の下にファイルを作って読み込ませてみる。どうやら iphone/hoge.js のように指定してやらないと読み込めないようだ。うーん。これだと個別のプラットフォームごとにload仕分けるような何かが必要?なのかな?

あと、ウィンドウの中身がひとつのファイルで表されるということで、外部で定義された変数は使えないようだ(例えばこの場合は var win1 は使うことができないので、win1.add(label1) などとしては駄目で、Titanium.UI.currentWindow.add(label1); とする必要がある)。なるほど?

というあたりまで読んで、KichenSink の Resources/examples あたりを読みながら実際に KichenSink を動かしてみた。思ったよりいろいろできるんだなぁこれ。

Titanium Mobile Community Edition では モバイルデバイスデバッグ はできない

ということで、そろそろ自分で書いた部分が増えてきたのでブレークポイントでも仕掛けてみようかなーと思ったら、Titanium Mobile Community Edition では モバイルデバイスデバッグ はできないってのは iOS シミュレータ でもだめなのねこれ。うむー。そうなのかー。そうなのかー。

Console に log を吐く

Titanium Mobile Community Edition だとデバッグできないということで。で、毎月いくらかを払わねばならないという課金体制がどうにも残念な感じ(個人的に売り切りの方が好きというだけですが)なので、とりあえずは他の方法でなんとかできないかなぁと考えてみて、とりあえず log を吐かせてみることにする。

http://code.google.com/p/titanium-mobile-doc-ja/wiki/guides_app_log

によると、log を吐くには Titanium.API.info() というのなどが使えるらしい。使えるものは以下の通り。

  • Ti.API.error('致命的なエラー');
  • Ti.API.warn('警告');
  • Ti.API.info('情報');
  • Ti.API.debug('デバッグ情報');

(Ti てのは Titanium の省略形)

ステップ実行できないとかメンドクサイけれど、まぁ、printf デバッグができるなら少しは戦えるよね。

HTTP で何かを取得する

HTTP で何かを取得するには Titanium.Network.createHTTPClient() で作った XmlHTTPRequest? か何かのオブジェクトを使う。

http://code.google.com/p/titanium-mobile-doc-ja/wiki/guides_network_httpclient

を参考にすると良い感じ。とりあえずは

var xhr = Titanium.Network.createHTTPClient();
xhr.onload = function()
{
handler(this.responseText);
}
xhr.open('POST', "http://www.google.co.jp/search");
xhr.send({q: 'hoge'});

というような感じで onload にハンドラ、open でメソッドとURL、POSTの場合は send にPOSTで送信するモノの内容を JSON形式 で突っ込んでおく、というもののようだ。
(まぁ、この例だと POST は許されてないから駄目だよというエラーになっちゃうけどネ)

app.js 以外のファイルを使う、そのに

Titanium Mobile で複数の .js ファイルを使うにはいくつか方法があるみたいです。

Titanium Mobile 別JSファイルの呼び出し@UMIGAME

によれば、

  • Titanium.include(`ファイル名.js`)
  • Titanium.UI.cretaeWindow({ url:`ファイル名.js`})
  • require('ファイル名')

の三種類?があって、私の望んでいるのは require() によるものが一番近いっぽい。とりあえずいろいろ書きなおし……

アプリケーションの設定を残しておく

http://code.google.com/p/titanium-mobile-doc-ja/wiki/guides_app_properties

によると、Titanium.App.Properties を使って Key value store っぽく情報を残しておけるようだ。なるほど…… あとで設定を保存できるようにしよう。

システム側で用意されているアイコン

どうやらシステム側で用意してくれているアイコンというものがあるらしい。

http://code.google.com/p/titanium-mobile-doc-ja/wiki/howto_button_icon

アイコン作るのがめんどくせーとか思った私にはいいかもしれない。

実機でエラー? 何故か落ちる

ということで、その他 XML の DOM とか TableView とか ImageView とか Label とかでごにょごにょと書いて、なんとなく EVE OnlineAPI を使って自分のキャラクタのリストを取得 → それらのキャラクタのトレーニング中のスキルを表示する、というあたりまでできた。やったね!


(自分の思ったような何かが表示できた!)

あ、EVE OnlineAPI 周りはここが詳しそうだったのでそのまま参考にしました。

http://wiki.eve-id.net/APIv2_Page_Index

ということで、実機の iPhone 3GS に転送して動かしてみたのだけれど、Titanium Mobile のロゴがでた後すぐにハングしたのだかなんだかで終了してしまう。何故だ。

デバッガ越しに起動してブレークポイントを〜とかができるわけではないので何が原因なのかよくわからない……うむむむ。

……ということで今回はこのあたりまででまた今度!

node.js 使ってみた

ながいながいまえふり(読み飛ばし推奨)

(関数型言語使ってないけれど)最近、プログラムを書くときには関数型言語で書く、もしくは関数型っぽく書くといろいろ考えることが減っていいんじゃないかと思っていて、それと関連して Erlang とかのアクターモデルが私の望んでいるスタイルにぴったりなんじゃないかと思っているわけです。

というのは、thread とか使ってる時に mutex lock とかしなくちゃいけないとかもうね。考えたくないわけですよ。これって関数型言語でよく言われる「副作用が無い」という状態にしておけば、そもそも mutex lock なんて概念は使わなくていいわけです。たとえば、五月雨式にやってくる要求に対して個別に thread を立てて対応をする、ってな事はよくやるわけですが、この時作る thread を副作用の無いものにしておくと mutex lock とかしなくて済んでいいですよね == 考える事減るよね、となるわけです。
といっても、それだけではうまく動かなくて、副作用のある事が書きたくなったりするわけです。例えば、複数のアクセスが同時に来るときに、そのうち一つだけに何か特別な値を返したい時です。この例だと「特別な値を返した事があるかどうかを記憶している部分」を共有して、書き換えないといけない、ということで、副作用を伴う事になります。ここで、アクターモデルだとアクター間でのメッセージパッシングという仕組みでこの副作用をある程度解消できているんじゃないかなぁと思っています。
というのは、アクターモデルだとアクターごとに状態がある事になる……のかな、たぶん。……のですが、とりあえず副作用の無い部分は関数の形で実装して、副作用が発生する所で他のアクターに対してメッセージを投げる、という動作にしてしまえば、個々の関数に関しては副作用の無いものが書けるのかなぁ、という気がしています。例えば、前の例だと複数のリクエストを受けた時にそのリクエストの数分だけアクター A, B, C を作って、それらのアクター A, B, C がある一つのアクター α にメッセージを投げると、そのアクター α が持っている内部状態を更新しつつ、アクター A, B, C それぞれに別のメッセージを投げ返す(うち、一つは特別な値を返す)、という事で実装すればいい、という事になります(蛇足: この場合はアクター α は副作用がある関数を実装していることになります。実際の所、Erlang の分散DB Mnesia はそういう感じで動いているっぽいです)。
ということで、「副作用がない関数を書こう」というのと、「アクターモデルってイイカモ?」というのが最近私がかぶれている概念なわけです。

あ、Erlang というか関数型言語自体、全然使っていないため、ここまで書いてきた事は全部私の理解したつもりになっているにわか知識からの想像です。ということで嘘八百が書いてあるかもしれないので鵜呑みにすると大変なことになるかもわかりません。というかよくわかってる人はコメント欄ででも間違いを指摘して晒しあげておいて頂けると嬉しいです。もちろん、こっそり教えていただくのでも構いません。:D

で、です。Erlang すごいじゃん Mnesia は真の分散DBだぜ(CodeZineの記事の冒頭による)、凄いぜすごいぜ最強なんじゃね?と思って Erlang を使ってみようかなぁと思ったのだけれど、いろいろと覚えなければならないことが多くて大変だなぁ、と感じていじれていなかった所に、「node.js ってなのがあってー」という話題を聞きつけたり、node.js についての Erlang のコミュニティの反応 みたいな例を見たりして、案外 node.js もいいかもわからんね?なんか勢いあるみたいって所とか手続き型っぽい書き方とかそれでもクロージャが書けるのでメッセージパッシングっぽい何かとして非同期I/Oを隠蔽してるし、私としては JavaScript なら Erlang より書きやすいし。とか考えて、node.js が気になっていたわけです。

ということで、node.js をとりあえず使ってみようとしてみましたよ、というお話です。

node.js とは

node.js は「JavaScript で書けるサーバをつくるための何かのうちの一つ」のようです。以下のような特徴を持ちます。

  • 非同期I/O の塊なので、基本的にクロージャを使っての関数呼び出しの連鎖でアプリケーションを記述する(たぶん、このあたりは jQuery を使ってた人たちとかは馴染みやすい気がする)
  • V8 JavaScript Engine を使っているので JavaScript といっても遅いわけではない
  • libev を使って 非同期I/O を実現している(多分 C10K問題 への対応はOKな気がする)
  • JavaScript というだけあって、Web屋さん方面の人々とかが押し寄せてきているらしく、活気があるっぽい?
  • npm というモジュールマネージャがあって、なにやら便利なモジュールがいっぱいある(sudo curl http://... | sh ってするとインストール完了ってどうなのよ…… とかいうのはちょっと気になるケド)

開発環境を手に入れる

node.js 本体を手に入れる

http://nodejs.org/ から先日リリースされた v0.4.0(stable release は 0.(n*2).* (n は 0, 1, 2, ...)らしいです)を download してきて

% ./configure; make; sudo make install

で install は完了です。
あ、make するのに python とか libopenssl とかがあるといいです(python は必須)。
何故か手元の Windows7 64bit版 では configure の時点で python が変なエラーを吐いて駄目でした。まぁ localhost で動く必要はなくなったのでいいですけれども。

npm を手に入れる

npm は node.js のモジュールをインストールしやすくするためのものです。

% curl http://npmjs.org/install.sh | sudo sh

で、install は終了なんですが…… ネットワークの先の sh script をそのまま sudo した sh に食わせるのって…… と思いますた。
でも、その後で

% sudo npm install express

とかしちゃってるのでもうイイですよねたぶん。

node-inspector をインストールする

node-inspector は node.js のデバッグをできるようにする何かです。
すにぺっとさんの node.js でのデバッグ方法 という記事が分かりやすかったのでそこを読んでおくといい気がします。

すにぺっとさんの所でも書かれているのですが、このデバッガは Google Chrome等 の Webkitを使ったブラウザが必要です。

すにぺっとさんの記事の時点では 0.4.* は出ていなかったので少しトリッキーな事をしているようですが、もう 0.4.* が出ているので何も考えずに

% sudo npm install node-inspector

とするだけで良いです。

その他、使いそうなモジュールをいくつか入れる

今回の記事部分では使いませんでしたが、google先生 にいろいろ聞いていた所、express というフレームワークejs というテンプレートエンジン、socket.io が便利そうなので、npm で入れておきました。

% sudo npm install express
% sudo npm install ejs
% sudo npm install socket.io

socket.io については、クライアント側のものも必要っぽいです。

とりあえずデバッグ実行してみる

デバッグ環境の node-inspector の使い方が少しトリッキーでした。というのは、

  • node-inspector は node とは別に起動しておく必要がある
  • node-inspector は localhost からの接続しか受け付けないので、chrome の動いている host と別の host から使うには ssh の port forward のような事をする必要がある

という点でした。

私の場合、

localhost% ssh -L 8080:localhost:8080 node-inspectorの動いているホスト

という形で ssh で port forward させて、http://localhost:8080デバッグ用にひらいて解決しました。

ということで、起動する順番としては、

% node-inspector &
% node --debug hoge.js

というような感じで node-inspector と node.js を実行して、chromehttp://localhost:8080/debug?port=5858 とか(default なら http://localhost:8080 で ok)を開くとデバッガの画面が表示されました。

ブレークポイントで止めたあと、変数の中身とかも詳しくみられます。

いいかんじです!

ちなみに、複数人で同時に同じホストで開発する時とかではポート番号がかぶってしまいそうですが、その場合は node --debug への引数としてデバッグ用のポート番号を指定して、node-inspector には URL の後ろに /debug?port=... の形式でそのデバッグのポート番号を指定すれば良いようです。
具体的には、

% node-inspector &
% node --debug=15858 hoge.js

としたのなら、http://localhost:8080/debug?port=15858 へとアクセスすれば、デバッガへと接続できます。

とりあえず、これで初期設定としてはいい感じでしょうか。うまく何かが作れたら続くかもわかりません。