ネットワークを扱うフレームワークを新規に作る必要はない。 このフレームワークは非常に多くのアプリで検証されており、必要な機能のほとんどを含んでいる。
- iOS 7+の場合、AFNetworking 2.xの最新版を使う
- iOS 5-6の場合、AFNetworking 1.xの最新版を使う
- iOS 4.3の場合、AFNetworking 0.10.xの最新版を使う
Build Phases -> Link Binary With Librariesに以下のライブラリを追加する。
Security.framework
MobileCoreServices.framework
SystemConfiguration.framework
Prefix.pchに以下のインポート文を追加する。
#ifdef __OBJC__
#import <UIKit/UIKit.h>
#import <Foundation/Foundation.h>
+ #import <SystemConfiguration/SystemConfiguration.h>
+ #import <MobileCoreServices/MobileCoreServices.h>
#endif
主な機能
- ベースURLを設定することができ、リクエストは相対パスで行うことができる
- パラメータはDictionaryで指定することができる
- リクエストに共通で付加するデフォルトヘッダを設定することができる
- 認証、Content-Type、Acceptなど
- レスポンスの形式に応じてパースを自動的に行うことができる
- レスポンスをJSONオブジェクトとして取得するなど
- 接続先のネットワーク到達性を確認することができる
ガイドライン
- APIのエンドポイントごとに、対応するクラスをAFHTTPClientをサブクラスとして作成する
- シングルトンのインスタンスを返すクラスメソッドを作成する
- 同じ設定を何度も行わなくても良いようにするため
- ファイルをアップロードする場合は、-multipartFormRequestWithMethod:path:parameters:constructingBodyWithBlock:メソッドを使用する
- リクエストパラメータをJSONで送りたい場合は、parameterEncodingプロパティにAFJSONParameterEncodingを設定する
- AFHTTPClientのオペレーションキューにリクエストを入れる前に、リクエストオペレーションの設定をしたり、後で使うためにリクエストオペレーションを保持しておきたい場合は、-HTTPRequestOperationWithRequest:success:failureを使う
- URLリクエストオブジェクトで行いたい場合は、-requestWithMethod:path:parametersを使う
@interface SampleAPIClient : AFHTTPClient
+ (instancetype)sharedClient;
- (instancetype)initWithBaseURL:(NSURL *)url;
- (void)getSampleDataWithPath:(NSString *)relativePath
parameters:(NSDictionary *)parameters
success:(void (^)(AFHTTPRequestOperation *operation, id responseObject))success
failure:(void (^)(AFHTTPRequestOperation *operation, NSError *error))failure;
@end
@implementation SampleAPIClient
+ (instancetype)sharedClient {
static SampleAPIClient *_sharedClient;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
_sharedClient = [[SampleAPIClient alloc] initWithBaseURL:[NSURL URLWithString:kAPIBaseURL]];
});
return _sharedClient;
}
- (instancetype)initWithBaseURL:(NSURL *)url {
self = [super initWithBaseURL:url];
if (!self) return nil;
// JSON形式のレスポンスを扱う
[self registerHTTPOperationClass:AFJSONRequestOperation.class];
// すべてのリクエストにJSONを受け付けるAcceptヘッダをつける
[self setDefaultHeader:@"Accept" value:@"application/json"];
// すべてのリクエストにUser-Agentヘッダをつける
[self setDefaultHeader:@"User-Agent" value:@"sample"];
return self;
}
- (void)getSampleDataWithPath:(NSString *)relativePath
parameters:(NSDictionary *)parameters
success:(void (^)(SampleModel *model))success
failure:(void (^)(AFHTTPRequestOperation *operation, NSError *error))failure {
static NSDictionary * const defaultParameters = @{@"key1": @"value1", @"key2": @"value2"};
NSMutableDictionary *composedParameters = [defaultParameters mutableCopy];
[composedParameters addEntriesFromDictionary:parameters];
// GETメソッドでJSONを取得する
[self getPath:@"sample/data" parameters:composedParameters success:^(AFHTTPRequestOperation *operation, id responseObject) {
success([SampleModel parseResponse:responseObject]);
} failure:failure];
}
@end
- -networkReachabilityStatusプロパティで、接続先のネットワーク到達性を確認できる
- -setReachabilityStatusChangeBlock:メソッドで、接続先のネットワーク到達性に変化があった場合に呼ばれるコールバックを設定することができる
setImageWithURL:placeholderImage:
で、URLで指定した画像を非同期で取得し、イメージを設定できる- 画像をキャッシュする機能がある
- キャッシュが存在すればすぐにその画像を表示し、存在しなければplaceholderを表示してからURLで指定した画像を取得する
[imageView setImageWithURL:[NSURL URLWithString:@"http://example.com/image.png"] placeholderImage:[UIImage imageNamed:@"placeholder"]];
NSURLRequest *request = [client requestWithMethod:@"GET" path:urlPath parameters:nil];
AFURLConnectionOperation *operation = [[AFHTTPRequestOperation alloc] initWithRequest:request];
operation.outputStream = [NSOutputStream outputStreamToFileAtPath:filePath append:NO];
// ダウンロードのプログレスを表示する
[operation setDownloadProgressBlock:^(NSInteger bytesRead, long long totalBytesRead, long long totalBytesExpectedToRead) {
NSLog(@"progress: %f", (float)totalBytesRead / totalBytesExpectedToRead);
}];
// ダウンロードの成功、失敗を表示する
[operation setCompletionBlockWithSuccess:^(AFHTTPRequestOperation *operation, id responseObject) {
NSLog(@"completed");
} failure:^(AFHTTPRequestOperation *operation, NSError *error) {
NSLog(@"error: %@", error);
}];
// アプリが終了してもダウンロードを継続するよう設定する
[operation setShouldExecuteAsBackgroundTaskWithExpirationHandler:^{
// ダウンロード中断時に行う処理を記述する
}];
[client enqueueHTTPRequestOperation:operation];
- NSURLCacheを用いて、メモリとディスクのキャッシュサイズを指定する
- ネットワーク通信時に、ステータスバーのネットワークアクセスインジケータを表示する
- リクエストとレスポンスの内容をログに出力する
- ボディも表示したい場合は、ログレベルをAFLoggerLevelDebug設定する
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
// キャッシュサイズを設定
NSURLCache *URLCache = [[NSURLCache alloc] initWithMemoryCapacity:4 * 1024 * 1024 diskCapacity:20 * 1024 * 1024 diskPath:nil];
[NSURLCache setSharedURLCache:URLCache];
// ネットワーク通信時にステータスバーのインジケータを表示
[AFNetworkActivityIndicatorManager sharedManager].enabled = YES;
#ifdef DEBUG
// リクエストとレスポンスの内容をログに出力
[[AFHTTPRequestOperationLogger sharedLogger] startLogging];
#endif