Objective-C
iOS
afnetworking

AFNetworking を使って Web API のクライアントを作る方法

More than 3 years have passed since last update.

エラー処理等は省きます。

参考: http://cocoadocs.org/docsets/AFNetworking/2.0.0/Classes/AFHTTPSessionManager.html


APIManager.h

#import "AFHTTPSessionManager.h"


#ifdef DEBUG
#define API_BASE @"http://staging.api.example.com/"
#else
#define API_BASE @"http://api.example.com/"
#endif

@interface APIManager : AFHTTPSessionManager

// singleton
+ (instancetype)shared;

// 例えば News っていうリソースを取ってくるとして。
- (void)fetchNews:(void (^)(NSArray *news, NSError *error))handler;
@end



APIManager.m

#import "APIManager.h"

#import "News.h"

@implementation APIManager

+ (instancetype)shared
{
static APIManager *_shared = nil;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
_shared = [[self alloc] init];
});

return _shared;
}

- (instancetype)init
{
// NSURLSessionConfiguration も指定したい場合は
// initWithBaseURL:sessionConfiguration: を使う
// 未指定の場合 [NSURLSessionConfiguration defaultSessionConfiguration] が使われる。
if (self = [super initWithBaseURL:[NSURL URLWithString:API_BASE]]) {
// 何か設定しておきたいことがあればこのへんで。
// responseSerializer はデフォルトで AFJSONResponseSerializer
// requestSerializer はデフォルトで AFHTTPRequestSerializer
}
return self;
}

- (NSURLSessionDataTask *)dataTaskWithRequest:(NSURLRequest *)request
completionHandler:(void (^)(NSURLResponse *, id, NSError *))completionHandler
{
NSMutableURLRequest *mutableRequest = [request mutableCopy];
mutableRequest.timeoutInterval = 20.0; // なんか共通でやっときたいこと色々
return [super dataTaskWithRequest:mutableRequest completionHandler:completionHandler];
}

- (void)fetchNews:(void (^)(NSArray *, NSError *))handler
{
[self GET:@"/api/v1/news" parameters:nil success:^(NSURLSessionDataTask *task, id responseObject) {
NSArray *news = [News newsWithResponse:responseObject]; // News クラスのオブジェクトの配列を返すとして。
if (handler) {
handler(news, nil);
}
} failure:^(NSURLSessionDataTask *task, NSError *error) {
if (handler) {
handler(nil, error);
}
}];
}
@end


色々はしょってますが、大枠でこんな感じに API をラップしたメソッドをつくっていきます。

コントローラからはこんな感じで使うイメージ


NewsViewController.m

// 抜粋

[[APIManager shared] fetchNews:^(NSArray *news, NSError *error) {
if (!error) {
self.news = news;
[self.tableView reloadData];

} else {
// 何らかのエラー処理!!
}
}];