2013/02/21更新

[XCODE] iOSから非同期/同期にHTTPリクエストを送信する方法(Part2)

このエントリーをはてなブックマークに追加            

こんにちは、@yoheiMuneです。
以前ブログに書いた「iPhoneアプリからHTTPリクエストを送信して、データを受信する方法」で紹介したリクエスト送信方法より便利な送信方法があったので、ブログに書きたいと思います。

画像


iOSから非同期にHTTPリクエストを送信する

iOSからHTTPリクエストを送信する方法はいくつかありますが、以前の記事では、 Delegateを実装する必要があっていくかのメソッドを書かなきゃいけなかったので、面倒な感じでした。
今回紹介する方法は、実行結果をブロックの引数で受け取ることができ、いい感じに少ないコード量で実装できます。

以下が具体的な実装例です。
// 送信するリクエストを生成する。
NSURL *url = [NSURL URLWithString:@"http://www.yoheim.net/"];
NSURLRequest *request = [[NSURLRequest alloc] initWithURL:url];

// リクエストを送信する。
// 第3引数のブロックに実行結果が渡される。
[NSURLConnection sendAsynchronousRequest:request queue:[[NSOperationQueue alloc] init] completionHandler:^(NSURLResponse *response, NSData *data, NSError *error) {
  
  if (error) {
    // エラー処理を行う。
    if (error.code == -1003) {
      NSLog(@"not found hostname. targetURL=%@", url);
    } else if (-1019) {
      NSLog(@"auth error. reason=%@", error);
    } else {
      NSLog(@"unknown error occurred. reason = %@", error);        
    }
  
  } else {
    int httpStatusCode = ((NSHTTPURLResponse *)response).statusCode;
    if (httpStatusCode == 404) {
      NSLog(@"404 NOT FOUND ERROR. targetURL=%@", url);
      // } else if (・・・) {
      // 他にも処理したいHTTPステータスがあれば書く。
    
    } else {
      NSLog(@"success request!!");
      NSLog(@"statusCode = %d", ((NSHTTPURLResponse *)response).statusCode);
      NSLog(@"responseText = %@", [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding]);
      
      // ここはサブスレッドなので、メインスレッドで何かしたい場合には
      dispatch_async(dispatch_get_main_queue(), ^{
        // ここに何か処理を書く。
      });
    }
  }
}];
という感じです。引数にコールバック処理を渡す感じでコード量少なくいい感じに記載できます。
(最近JSばっかり書いててこのスタイルに慣れてるから、良いと感じるのかも。。)



同期リクエストを送る

同期リクエストも送ることができます。
// 送信するリクエストを作成する。
NSURL *url = [NSURL URLWithString:@"http://www.yoheim.net/"];
NSURLRequest *request = [[NSURLRequest alloc] initWithURL:url];

// リクエストを送信する。
NSError *error;
NSURLResponse *response;
NSData *data = [NSURLConnection sendSynchronousRequest:request returningResponse:&response error:&error];

// リクエスト結果を表示する。
// エラー処理は、上の非同期リクエストと同じ感じで。
NSLog(@"request finished!!");
NSLog(@"error = %@", error);
NSLog(@"statusCode = %d", ((NSHTTPURLResponse *)response).statusCode);
NSLog(@"responseText = %@", [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding]);

ただ、同期処理を送信するとリクエスト中UIが固まっちゃうので、注意です。
もし使うなら、サブスレッドなどで使うと良いかもしれません。こんな感じです。
// サブキューを作成して、処理をサブスレッドで実行する。
dispatch_queue_t sub_queue = dispatch_queue_create("sub_queue", 0);
dispatch_async(sub_queue, ^{

    NSURL *url = [NSURL URLWithString:@"http://www.yoheim.net/"];
    NSURLRequest *request = [[NSURLRequest alloc] initWithURL:url];
    
    NSError *error;
    NSURLResponse *response;
    NSData *data = [NSURLConnection sendSynchronousRequest:request returningResponse:&response error:&error];

    /* リクエスト結果に合わせて処理を書く */
});
リクエスト中にユーザー操作を受け付けたくない場合にも、画面にはIndicatorなどをクルクルとさせて動いているアピールをする必要はあるので、 メインスレッドをブロックしないように注意が必要です。



最後に

iOSでは、情報取得やAPI利用のためにHTTPリクエストを送信することも多いのではないでしょうか。
こーゆう小さなスニペットを集めておいて、開発効率アップにつなげたい次第です。

簡単な記事ですが最後までご覧頂きましてありがとうございました。





こんな記事もいかがですか?

RSS画像

もしご興味をお持ち頂けましたら、ぜひRSSへの登録をお願い致します。