手軽に別スレッドで 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 が入っています。
これを利用して、処理を分岐させて下さい。