JSCocoaのiPhone用インタラクティブコンソール
JSCocoaのページからリンクされたので日本語版をこっちにうつしました。
iviewで使っているUIViewのtransformがなかなか思い通りに操れなくて困っていて、だったらアプリにSpiderMonkeyを入れてHTTP経由で通信して試行錯誤できるよにすればいいやとUIMonkeyというのを作り始めたところで、既にそういうのがいくつかあるのをJohn Resig – JavaScript iPhone Appsで知ってショックーというかアホだったのでJSCocoaベースにちょこっと書き直しました。viewの階層構造やサイズを調べるのに便利です。

ファイルのコピー
svn checkout http://jscocoa.googlecode.com/svn/trunk/ jscocoa-read-only
してjscocoa-read-only/JSCocoa/JSCocoaの中身を全部自分のプロジェクトにコピーします。class.jsだけプロジェクトに追加した時に、ただのリソースファイルとして認識してほしいんだけどソースファイルとして認識されてしまうので、いったんclass.gifという名前でプロジェクトに追加して後から名前を変えたらうまくいきました(どうやるのが正しいんでしょう…)。
JSCocoa本体のほかにHTTPサーバのためのHttpd.m, Httpd.h, console.htmlを追加してください。console.htmlはCopy Bundle Reesourcesに入れてアプリケーションに組み込まれるようにしてください。
*_Prefix.pchの修正
JSCocoa用のヘッダファイルを追加します。
今回はインラインでUSE_JSCOCOAをdefineしていますが、デバッグビルドの時だけdefineするようにしたりすればいちいち書き換えたりする手間がなくなります。
#define USE_JSCOCOA 1
#if USE_JSCOCOA
#define JSCocoa_iPhone
#include "JavascriptCore.h"
#endif
main.mの修正
JSCocoaのサンプルコードiPhoneTest2とおんなじようにmain.mで初期化します。クラスHttpdは自分で作ったなんちゃってHTTPサーバです(最後参照)。
#if USE_JSCOCOA
// Fetch JS symbols
[JSCocoaSymbolFetcher populateJavascriptCoreSymbols];
// Load iPhone bridgeSupport
[[BridgeSupportController sharedController] loadBridgeSupport:[NSString stringWithFormat:@"%@/iPhone.bridgeSupport", [[NSBundle mainBundle] bundlePath]]];
// Load js class kit
id c = [JSCocoaController sharedController];
[c evalJSFile:[NSString stringWithFormat:@"%@/class.js", [[NSBundle mainBundle] bundlePath]]];
[[[Httpd alloc] initWithPort:38880] autorelease];
#endif
リンクするライブラリの追加
JSCocoaは関数呼び出しにlibffiを使っているので、プロジェクトの設定を開いてOther linker flagsに-lffiを追加します。
CGAffineTransformの追加
JSCocoaの中にiPhoneでだけ使われる構造体を定義しているiPhone.bridgesupportというXMLファイルがあります。これにCGAffineTransformを追加します(CGAffineTransformを使わないのであれば必要ありません)。
せっかくXMLファイルなのに構造体メンバを"で区切ってしかもそれを実体参照で書くという酷い仕様。下の行をてきとうにCGSizeを定義している下くらいに追加します。
<struct name='CGAffineTransform' type='{CGAffineTransform="a"f"b"f"c"f"d"f"tx"f"ty"f}'
type64='{CGAffineTransform="a"d"b"d"c"d"d"d"tx"d"ty"d}' />
ヘッダファイルからマシンフレンドリーな形式で生成して実行時コストを下げるか、ヒューマンフレンドリーにして手で書きやすくするかどっちかにするべきだと思います。
ブラウザで接続
そうしたらあとはアプリをふつうに起動すれば http://localhost:38880/ でアプリの中のJSCocoaに接続できるので、好きなタイミングでブラウザからJSCocoaにjsのコードを送り込んでアプリを操作できます。

JSCocoaではObjective-Cのクラス名、メソッド名でjsからもアクセスできるので、UIApplication.sharedApplicationからアプリ内のオブジェクトにアクセスできます。
メインウインドウのアルファを0.2に変えると


背景が透けて、暗くなります。
CGAffineTransformで横に3倍引き延ばしてちょっと右に100ピクセルずらすと


こうなります。
こういう試行錯誤や、使ったことのないクラスを触ってみるときに、Objective-Cのコードの上でやろうと思ったら毎回コンパイルし直す必要があるので時間がかかりますがjavascriptからできると細かい調整がすごく楽です。
View Tree Walk
takuma104さんが前に
iPhoneにWindowsでいうSpy++みたいなのがほしい。viewの階層構造がわかるやつ。
Twitter / takuma mori: iPhoneにWindowsでいうSpy++みたいな …
と言われていたのを思い出して、UIApplication.sharedApplication.subviewsからviewを列挙してjavascriptオブジェクトとしてみられるようにしてみました。HTMLで視覚的に再構築できればベストなんですけど、とりあえずFirebugのコンソールで値を確認できるようにしてみました。inspect view treeのリンクをクリックすると下の画面みたいにしてviewの階層構造を見ることができます。

JSCocoa感想
JSCocoaがNSArrayを自動的にjavascriptの配列として扱ってくれるのですが、これがあんまりうまくいってないみたいでlengthの値が入ってなかったりするとか、そういう微妙に変なところを配慮してあげればわりと使えそうなかんじでした。
自分が普段SpiderMonkeyにどっぷり浸かっているのでunevalがないとかE4Xがないとか分割代入できないとかもありましたがそうでなければふつうにjavascriptです。
About this entry
You’re currently reading “JSCocoaのiPhone用インタラクティブコンソール,” an entry on ku
- Published:
- 2008.11.23 / 12pm
- Category:
- debug, iPhone, javascript, tool

No comments
Jump to comment form | comments rss [?]