yo_waka's blog

418 I'm a teapot

Objective-Cはじめました

近々仕事で書くことになりそうなので先週からObjective-C勉強中。
新しい言語を覚えるのは楽しくていいですね。
StoryBoardでパーツペタペタ貼ってプロパティ設定してると昔触ったVB6を思い出します(遠い目


GUIを作るという意味ではJavaScriptやActionScript3と同じなので、考え方とかdelegeteとかのデザインパターンは特に問題ないのだけれど、やはりメモリ管理、特にBlocks使ってる箇所でEXC_BAD_ACCESS出まくったりで苦戦。。。
Blocksの中でself使ったらダメとか、上の関数で受け取った引数もそのまま入れるとダメ(な時がある)とか@propertyあまり使いこなせてない感とか、ちゃんと理解できるにはもう少しかかりそう><

Blocksとメモリ周りについて以下のブログが参考になりました。
IOS 開発で、EXC_BAD_ACCESS とさよならするための6つのルール
ARC : 循環参照


もっと慣れるためにもやっぱりアプリを作ってみないとね、ということでAPIからJSON受け取って表示するよくあるビューアーアプリを作ってみたのですが、Objective-CってHTTPリクエストのやりとりめちゃめんどくさくね?

毎回クエリーストリング文字列で作ったりURLエンコードするのめんどくさいし、URLConnectionのコールバックに渡すBlocks内でエラー判定してJSONデコードしたりとかコールバックが膨らみすぎてやばい。画面内で複数API叩いたりしてるとさらに倍増。

なのでもっと簡単にHTTPリクエストのやりとりが出来るライブラリを作ってみました。ザ・車輪。

コードはGitHubにあげました。久しぶりに個人用のGitHub使ったぜい。
waka/objc-Async
※ NSURLConnection#sendAsynchronousRequestを使ってるのでiOS5以上でないと動きません


中身はPromise/Aを実装したDeferredと、Deferredを使って非同期なGET/POSTリクエストを簡易化したHttpClientです。
JavaScriptでよくやるやり方ですね。
Deferredの実装は、以前JavaScriptでPromise/Aを実装したものObjective-Cで書き換えただけ!
Async下のソースファイルをコピーするだけで普通に使えます。

使い方はReadmeにも書いてあるけど、基本的にAPIのURLとNSDictionaryにしたURLパラメータを渡すとDeferredが返ってくるので、あとはHTTP通信後のコールバックとエラーバックをセットするだけ。

NSString *url = "http://path/to/api";
NSDictionary *params = @{@"username": @"waka", @"apiKey": @"secret"};

Deferred *deferred = [HttpClient doGet: url parameters: params];
[[deferred then: ^id(id resultObject) {
    // レスポンスのJSONはNSDictionaryに変換されて渡ってくる
    NSDictionary *data = (NSDictionary *)resultObject;
    NSLog(@"%@", data[@"hoge"]);
}] resolve: nil];


ユニットテストを書くためにGHUnitという非同期テストをサポートしているテスティングフレームワークを使ってみたのですが、これすごいいいですね。
何がいいってテストコードがアプリとしてビルドされるので、エミュレータないし実機でテストを走らせることができるのがいい。
おかげでLeaks使って簡単にメモリチェックできました。
導入もCocoaPods使うか、自分でmakeしてFrameworksに追加するだけなので簡単。
GUIのテストとユニットテストをこれ1つでできちゃいそうな感じなので便利に使っていこうと思います。