[iOS 7] AFNetworkingみたいな書き方ができるようになった!

iOS 7で一新された通信周り〜NSURLSessionってなに?〜でも書きましたが、iOS 7でAFNetworkingみたいな書き方で通信処理が実装できるようになりました!これは便利!
・・・と言いたいところですが、厳密に言うとiOS 7では非同期通信の実装がより簡単に書けるようになりました!ってな感じでしょうか。NSURLConnectionでもそれっぽく書けましたもんね。

少なくともNSURLConnectionよりはNSURLSessionで書いた方がより書きやすいです。実際にソースコードを見てみましょう。

WebサイトのHTMLを文字列として取得する例を見てみましょう。まずは、AFNetworkingを使った場合の書き方です。

AFNetworkingを使った場合
NSURL *url = [NSURL URLWithString:@"https://classmethod.jp/"];
NSURLRequest *request = [NSURLRequest requestWithURL:url];

AFHTTPRequestOperation *operation = [[AFHTTPRequestOperation alloc] initWithRequest:request];

[operation setCompletionBlockWithSuccess:^(AFHTTPRequestOperation *operation, id responseObject) {
    // 通信が正に常終了したときの処理
    NSLog(@"%@", operation.responseString);
} failure:^(AFHTTPRequestOperation *operation, NSError *error) {
    // 通信が異常終了したときの処理
    ・・・
}];

// 通信開始
[operation start];

これをNSURLSessionを使って書いてみましょう。

NSURLSessionを使った場合
NSURLSession *session = [NSURLSession sharedSession];

NSURL *url = [NSURL URLWithString:@"https://classmethod.jp/"];
NSURLRequest *request = [NSURLRequest requestWithURL:url];

NSURLSessionTask *task = [session dataTaskWithRequest:request
                                    completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) {
                                        if (error) {
                                            // 通信が異常終了したときの処理
                                            ・・・
                                            return;
                                        }

                                        // 通信が正に常終了したときの処理
                                        NSLog(@"data : %@", [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding]);
                                    }];

// 通信開始
[task resume];

ほとんど同じように書けますね。また、以下のように直接URLを指定することもできます。

NSURLSession *session = [NSURLSession sharedSession];

NSURL *url = [NSURL URLWithString:@"https://classmethod.jp/"];

NSURLSessionTask *task = [session dataTaskWithURL:url
                                completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) {
                                        if (error) {
                                            // 通信が異常終了したときの処理
                                            ・・・
                                            return;
                                        }

                                        // 通信が正に常終了したときの処理
                                        NSLog(@"data : %@", [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding]);
                                }];

// 通信開始
[task resume];

非常に簡単に書けるようになりましたね!ちなみにデリゲートパターンで書く場合は以下のように書きます。以下のサンプルではViewControllerで呼び出してる感じです。

@interface ViewController () <NSURLSessionDataDelegate>

@end

@implementation ViewController

- (void)viewDidAppear:(BOOL)animated
{
    [super viewDidAppear:animated];
    
    NSURLSession *session = [NSURLSession sessionWithConfiguration:[NSURLSessionConfiguration defaultSessionConfiguration]
                                                          delegate:self delegateQueue:[NSOperationQueue mainQueue]];
    

    NSURL *url = [NSURL URLWithString:@"https://classmethod.jp/"];
    
    NSURLSessionTask *task = [session dataTaskWithURL:url];
    
    [task resume];
}

- (void)URLSession:(NSURLSession *)session dataTask:(NSURLSessionDataTask *)dataTask didReceiveData:(NSData *)data
{
    NSLog(@"%s", __func__);
}

今回はここまで!次回はNSURLSessionUploadTaskNSURLSessionDownloadTaskについて書きたいと思います。