PonyDebugger v0.2.1を試してみた


v0.2.1-beta1 でのメモ。 Xcodeは4.6。

[PonyDebugger](https://github.com/square/PonyDebugger)はiOSアプリをChrome Developer Toolsを使ってリモートデバッグできるツール。大きく３つの機能がある。

* Network Traffic Debugging
* Core Data Browser
* View Hierarchy Debugging

## プロキシサーバのセットアップ

**ponyd**というPonyDebuggerのプロキシサーバを挟んでChrome Developer Toolsから閲覧する。

というわけでponydをインストールする。XcodeのCommand Line Toolsが必要なのでXcodeの設定のDownalodsタブから入れておくこと。ponydについては[こちら](https://github.com/square/PonyDebugger/blob/master/README_ponyd.rst)にREADMEがある。

```bash:
curl -sk https://cloud.github.com/downloads/square/PonyDebugger/bootstrap-ponyd.py | \
  python - --ponyd-symlink=/usr/local/bin/ponyd ~/Library/PonyDebugger
```

上記のコマンドだと~/Library/PonyDebugger/bin/ponydにインストールされ、/usr/local/bin/ponydにシンボリックリンクが貼られる。/usr/local/binにパスが通っていれば以下で実行できる。

```bash:
ponyd serve --listen-interface=127.0.0.1
```

するとブラウザで http://localhost:9000 が閲覧可能になる。


## iOSアプリ側の作業

iOSアプリ側にPonyDebugger iOS Clientを組み込む。モジュールはiOS5以上でARCが有効でSocketRocketというWebSocketクライアントを使っている。

pod search Pony実行したらPonyDebugger (0.0.1)が見つかったので[CocoaPods](http://cocoapods.org/)で入れてみる。

しかし[0.0.1のpodspec](https://github.com/CocoaPods/Specs/blob/master/PonyDebugger/0.0.1/PonyDebugger.podspec)はコミットが31d05eb56b2d1b04e815579ba15b0b7c4104596eになっていてREADMEにある例を試そうとしたらautoConnectなんて定義されてねーよと怒られたのでPodspecを置き換える。

0.2.1のpodsecを作ろうかと思ったのだがXcode 4.6の修正らしきものがその後にコミットにあったので0.0.1を修正することにした。~/.cocoapods/master/PonyDebugger/0.0.1/PonyDebugger.podspecのs.sourceにあるコミット指定を外す。

```ruby:~/.cocoapods/master/PonyDebugger/0.0.1/PonyDebugger.podspec
  s.source       = { :git => "https://github.com/square/PonyDebugger.git" }
```

```ruby:Podfile
platform :ios,'5.0'
pod 'PonyDebugger'
```

pod installするとframeworkの依存関係も解決してくれる。試したときはPods.xcconfigのOTHER_LDFLAGSが参照されておらずリンクエラーがでたのでTARGETのOther Linker Flagsに$(inherited)を追加しておいた。

次に以下のようなコードを追加した。

```objectivec:AppDelegate.m
#import <PonyDebugger/PonyDebugger.h>

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
#if DEBUG    
    PDDebugger *debugger = [PDDebugger defaultInstance];
    [debugger enableViewHierarchyDebugging];
    [debugger enableCoreDataDebugging];
    [debugger enableNetworkTrafficDebugging];
    [debugger forwardAllNetworkTraffic];
    [debugger connectToURL:[NSURL URLWithString:@"ws://localhost:9000/device"]];
#endif
```

## 結果

アプリを実行すると http://localhost:9000 に接続中の一覧が表示され、アプリ名をクリックするとdevtoolが表示される。

とりあえず試したプロジェクトで確認できたのはView Hierarchy Debuggingだけ。Core Data Browserについては単にCoreDataを使っていなかったので未確認。Network Traffic DebuggingについてはNSURLConnectionDelegateプロトコルの実装を置き換えている都合上、例えば以下のようなコードから通信データをponydに送りつけるのは難しいようだ。

```objectivec:
[NSURLConnection sendAsynchronousRequest:request
                                       queue:[NSOperationQueue mainQueue]
                           completionHandler:^(NSURLResponse *response, NSData *data, NSError *error) {
}];
```

## その他

* アプリのプロセスが変わるたびにページを変えないといけない。単純にインクリメントしているのでURLのpageパラメータを増やせばいい ```http://localhost:9000/devtools/devtools.html?host=localhost:9000&page=1```
* Chrome以外のブラウザでも表示できる。ChromeのDeveloper Toolsで見ているのではなくて、Chrome Developer Tools相当のページをponydが返している模様。ただWebKitベースじゃないとレイアウトが崩れる。
* ```ponyd serve --listen-interface=0.0.0.0```でプロキシサーバを実行して、PDDebugger::connectToURLでホスト側のIPアドレスを指定したら実機でも動作した
* rubyは問題なかったがponyd実行中にローカルのphp5.4のビルドインWebサーバからレスポンスが返ってこなくなった