Objective-C
iPhone
Xcode
iOS

AFNetworking 2.0 のまとめ

More than 3 years have passed since last update.

概要

2.0になってから更にシンプルに記述できるようになっています。

下記が必須要件となっていますので導入前に確認してください。

  • Xcode 5以上
  • iOS 6.0以上

大きな変更点としてドキュメントにあるようにiOS7以降のサポートのみでよければAFHTTPSessionManagerのサブクラスを作成して実装することが推奨されています。
iOS6やそれ以前のバージョンをサポートする場合の選択肢としてAFHTTPRequestOperationManagerが用意されています。

ここでは主にAFHTTPRequestOperationManagerの使い方について触れておきます。

使い方

インストールもCocoaPodsで簡単に導入できますので、下記Podfileをプロジェクトのルート直下に作成してインストールしましょう。

platform :ios, '7.0'
pod "AFNetworking", "~> 2.0"

インストールできたら後はこの記述のみでJSONにパースするとこまでやってくれます。

AFHTTPRequestOperationManager* manager = [AFHTTPRequestOperationManager manager];
[manager GET:@"http://hoge/sample.json"
      parameters:nil success:^(AFHTTPRequestOperation *operation, id responseObject) {
        NSLog(@"response: %@", responseObject);
    } failure:^(AFHTTPRequestOperation *operation, NSError *error) {
        NSLog(@"Error: %@", error);
    }];

POSTでパラメータを設定する場合

AFHTTPRequestOperationManager* manager = [AFHTTPRequestOperationManager manager];
NSDictionary* param = @{@"param1" : @"value1", @"param2" : @"value2"};
[manager POST:@"http://hoge/sample.json" parameters:param success:^(AFHTTPRequestOperation *operation, id responseObject) {
        NSLog(@"response: %@", responseObject);
    } failure:^(AFHTTPRequestOperation *operation, NSError *error) {
        NSLog(@"Error: %@", error);
    }];

結果が通常のレスポンスの場合

AFHTTPRequestOperationManager* manager = [AFHTTPRequestOperationManager manager];
manager.responseSerializer = [AFHTTPResponseSerializer serializer];

としてAFHTTPResponseSerializerをセットしておきましょう。
でないとJSONのパースエラーになります。

レスポンスがXMLの場合少し面倒です。

AFHTTPRequestOperationManager* manager = [AFHTTPRequestOperationManager manager];
manager.responseSerializer = [AFXMLParserResponseSerializer serializer];
// 許可するContentTypeの設定が必要
manager.responseSerializer.acceptableContentTypes = [NSSet setWithObject:@"application/rss+xml"];

結果のresponseObjectがNSXMLParserなので自前でパースする必要があります。
ここも自動でパースしてくれれば言う事無しです。

他にもリクエストパラメータをJSONにしたい場合には、

AFHTTPRequestOperationManager *manager = [AFHTTPRequestOperationManager manager];
manager.requestSerializer = [AFJSONRequestSerializer serializer];

だけで自動でやってくれます。

通信ログについて

通信の詳細なログが見たい時はAFNetworkActivityLoggerを別途インストールするとリクエストヘッダー、レスポンスヘッダーもログ出力してくれます。

platform :ios, '7.0'
pod "AFNetworking", "~> 2.0"
pod "AFNetworkActivityLogger", "~> 2.0"

PodfileにAFNetworkActivityLoggerを追加してインストールします。

AppDelegate.m -application:didFinishLaunchingWithOptions::にログを開始する処理を記述します。

[[AFNetworkActivityLogger sharedLogger] startLogging];

ログレベルをAFLoggerLevelDebugにすればリクエストヘッダー、レスポンスヘッダーを含む通信のやりとりをログに出力できます。

[[AFNetworkActivityLogger sharedLogger] setLevel:AFLoggerLevelDebug];

GTMHttpFetcherのように通信ログをHTMLファイルで別途出力してくれれば言うことなしなんですけどね。

キャッシュポリシー、タイムアウトについて

AFHTTPRequestOperationManagerにはキャッシュポリシーとタイムアウトを設定するパラメータがありません。
現状で対応しようとするとAFHTTPRequestOperationManagerを継承したクラスを作って下記メソッドを追加するといった個別の対応をする必要があります。
カテゴリを使ってメソッドを追加してもよさそうです。

- (AFHTTPRequestOperation *)GET:(NSString *)URLString
                     parameters:(NSDictionary *)parameters
                timeoutInterval:(NSTimeInterval)timeoutInterval
                    cachePolicy:(NSURLRequestCachePolicy)cachePolicy
                        success:(void (^)(AFHTTPRequestOperation *operation, id responseObject))success
                        failure:(void (^)(AFHTTPRequestOperation *operation, NSError *error))failure
{
    NSMutableURLRequest *request = [self.requestSerializer requestWithMethod:@"GET" URLString:[[NSURL URLWithString:URLString relativeToURL:self.baseURL] absoluteString] parameters:parameters];
    request.timeoutInterval = timeoutInterval;
    request.cachePolicy = cachePolicy;
    AFHTTPRequestOperation *operation = [self HTTPRequestOperationWithRequest:request success:success failure:failure];
    [self.operationQueue addOperation:operation];

    return operation;
}

もしくはAFHTTPRequestOperationManagerを使用せずAFHTTPRequestOperationを直接使用することでも対応できます。

NSURL *URL = [NSURL URLWithString:@"http://hoge/sample.json"];
NSURLRequest *request = [NSURLRequest requestWithURL:URL cachePolicy:NSURLRequestReloadIgnoringLocalCacheData timeoutInterval:60.0];
AFHTTPRequestOperation *operation = [[AFHTTPRequestOperation alloc]
                                         initWithRequest:request];
[operation setCompletionBlockWithSuccess:^(AFHTTPRequestOperation *operation, id responseObject) {
        NSLog(@"response: %@", responseObject);
    } failure:^(AFHTTPRequestOperation *operation, NSError *error) {
        NSLog(@"Error: %@", error);
    }];

[operation start];

セキュリティポリシー

テスト環境などでSSL通信をする際にオレオレ証明書(自己署名証明書)を使っている場合は、AFHTTPRequestOperationManagerにオレオレ証明書を許可する設定を行うことで通信できます。

AFHTTPRequestOperationManager *manager = [AFHTTPRequestOperationManager manager];
manager.securityPolicy.allowInvalidCertificates = YES;
// 以降は通常通りAFHTTPRequestOperationManagerを使って通信を行う

まとめ

NSURLSessionの登場によって今後はNSURLConnectionがベースとなっているAFHTTPRequestOperationManagerではなくAFHTTPSessionManagerが主流になると思います。
現状ではiOS6のサポートが必要なアプリも多いと思いますので、AFHTTPRequestOperationManagerをメインに使いつつ、可能なところからAFHTTPSessionManagerにシフトしていけばよいでしょう。