2009-08-19
手軽に別スレッドで HTTP 通信を行う Objective-C のライブラリを作りました
iPhone アプリ開発の手始めに、NSURLConnection と NSOperation を組み合わせた Simple Http Client というモジュールを作りました。
使い方は、付属のテストコードを読んで頂けると、簡単に理解できると思います。
とても行数が少ないので、作る価値があったのか謎ですが(w;
cooldaemon’s SimpleHttpClient at master - GitHub
初めての Objective-C なので、突っ込み&添削は大歓迎です。
機能追加しました。詳細は、SimpleHttpClient に JSON と XML のフィルタを追加しました をご参照ください。
HTML フィルタも追加しました。HTML に対して XPath が使えます。
NSOperationQueue を外部から与えられるようにしました。当たり前の事ですが、スレッドを管理するキューは、一つの iPhone アプリに対して、一つで十分だと思います。
SimpleHttpClient を用いた iPhone アプリのサンプルプロジェクトを公開しました。
テストコードの解説
初期化
SimpleHttpClient *client = [[SimpleHttpClient alloc] initWithDelegate:self];
まずは、SimpleHttpClient のオブジェクトを作ります。
引数として delegate を渡していますが、リクエスト毎に delegate を変更する事も出来ます。
GET リクエスト
例えば、下記のような GET リクエストを発行したいとします。
http://foo.bar/search?q=iphone&q=osx&lr=lang_en
その場合は、下記のような辞書オブジェクトを作成し・・・
NSMutableDictionary *params = [NSMutableDictionary
dictionaryWithObject:[NSArray arrayWithObjects:@"iphone", @"osx", nil]
forKey:@"q"
];
[params setObject:@"lang_en" forKey:@"lr"];
辞書オブジェクトを JSON 風に表現すると下記のような感じです。
{ q : ['iphone', 'osx'], lr : 'lang_en' }
Value は、NSArray と NSString 以外は無視されるので気をつけて下さい。
これを、先ほど作成した SimpleHttpClient のオブジェクトに登録します。
[client
get:@"http://foo.bar/search"
parameters:params
context:@"iphone"
];
context は、後ほど説明します。
この時点で、別スレッド上で GET リクエストが実行されます。実際には、負荷が高ければキューに積まれ、負荷が下がるのを待ってから実行されるのですが、この辺りは、NSOperation と NSOperationQueue 任せです。
POST リクエスト
上記の 'get' を 'post' に変更します。
[client
post:@"http://foo.bar/search"
parameters:params
context:@"iphone"
];
データの受信
NSURLConnection でよく使われるメソッドだけラップしてあります。
気をつけるべき点は、別スレッドで同時に動いているので、一つの delegate にメッセージが集中する事です。(リクエスト時、個別に delegate を指定した場合は別です。)
その為、リクエスト時に指定した context を利用して処理を分岐させます。
例えば、didReceiveResponse を受け取る場合は、下記のようにします。
- (void)simpleHttpClientOperation:(SimpleHttpClientOperation *)operation didReceiveResponse:(NSHTTPURLResponse *)response { [_response setObject:response forKey:operation.context]; }
operation.context には、リクエストを登録する際に引数として渡した context が入っています。
これを利用して、処理を分岐させて下さい。
その他
GET、POST 共に priority を指定できます。緊急度の高いリクエストを優先的に行ったり、暇な時に行えば良いリクエストを後回しにしたりできます。
詳細は、NSOperation のマニュアルをご参照ください。
もし利用者がいらっしゃるようでしたら、もう少し、マシな解説を書きます。
- 12 http://www.google.co.jp/search?hl=ja&client=firefox-a&rls=org.mozilla:ja:official&hs=wfz&q=Mnesia+ram_copies+disc_copies&btnG=検索&lr=lang_ja
- 10 http://reader.livedoor.com/reader/
- 8 http://twitter.com/ssig33
- 6 http://blog.blueblack.net/item_164
- 6 http://d.hatena.ne.jp/rdera/20090113/1231819016
- 6 http://www.google.co.jp/search?sourceid=navclient&hl=ja&ie=UTF-8&rlz=1T4HPNN_jaJP337JP337&q=yum+mysql+5.0
- 4 http://twitter.com/
- 3 http://b.hatena.ne.jp/add?mode=confirm&title=neocomplcache + snipMate %u306E%u63A5%u7740%u5264 snipMate_complete %u3092%u8A66%u3057%u3066%u307F%u308B - cooldaemon%u306E%u5099%u5FD8%u9332&url=http://d.hatena.ne.jp/cooldaemon/20090810/124989
- 3 http://bitbucket.org/ns9tks/vim-autocomplpop/wiki/JapaneseManual
- 3 http://www.google.co.jp/search?hl=ja&client=firefox&rls=org.mozilla:ja:official&hs=2Co&q=cooldaemon&btnG=検索&lr=lang_ja