例えばサーバからjson形式で情報を取得する処理を共通化する際に、
指定するURLによって取得するデータもデータを保持するモデルクラスも異なる場合、
取得したデータのモデルクラスへの変換処理をブロックで渡すことで簡潔に書けたりします。
共通処理
ContentsManager.m
// 外部サーバからコンテンツ情報を取得
- (void) fetchContentnsInfo: (NSString *)url completion:(void (^) (NSArray *contentsList, NSURLResponse *response, NSError *error))completion json2Model:(NSArray* (^) (NSArray *jsonArray))json2Model
{
NSURLSession *session = [NSURLSession sharedSession];
NSURLSessionDataTask *task = [session dataTaskWithURL:[NSURL URLWithString:url]
completionHandler:^(NSData *data, NSURLResponse *response, NSError *error)
{
// 通信が異常終了した場合
if (error) {
if (completion) {
completion(nil, response, error);
}
return;
}
// 通信が正常終了した場合
NSError *jsonError = nil;
NSArray *jsonArray = [NSJSONSerialization JSONObjectWithData:data options:0 error:&jsonError];
// JSONエラーチェック
if (jsonError != nil) {
if (completion) {
completion(nil, response, jsonError);
}
}
// 結果からモデルオブジェクトを生成
NSArray *contentsList = json2Model(jsonArray);
// 生成したモデルオブジェクトをcompletionブロックで返す
if (completion) {
completion(contentsList, response, error);
}
}];
// 通信開始
[task resume];
}
共通処理呼び出し
共通処理の引数に取得したjsonデータのモデルクラスへの変換処理をブロック(json2Model)で渡す。
AnimeListViewController.m
[[ContentsManager sharedManager] fetchContentnsInfo:
@"http://aaa.bbb/ccc.json"
completion:
^void (NSArray *contentsList, NSURLResponse *response, NSError *error) {
// 取得したアニメ情報を設定
self.animeList = contentsList;
}
json2Model:
^NSArray* (NSArray *jsonArray) {
NSMutableArray *animeList = [NSMutableArray new];
for (NSDictionary *anime in jsonArray) {
Anime *tmpAnime = [[Anime alloc] initWithJSONObject:anime];
[animeList addObject:tmpAnime];
}
return [animeList copy];
}];
ChapterListViewController.m
[[ContentsManager sharedManager] fetchContentnsInfo:
@"http://xxx.yyy/zzz.json"
completion:
^void (NSArray *contentsList, NSURLResponse *response, NSError *error) {
// 取得したチャプター情報を設定
self.chapterList = contentsList;
}
json2Model:
^NSArray* (NSArray *jsonArray) {
NSMutableArray *chapterList = [NSMutableArray new];
for (NSDictionary *chapter in jsonArray) {
Chapter *tmpChapter = [[Chapter alloc] initWithJSONObject:chapter];
[chapterList addObject:tmpChapter];
}
return [chapterList copy];
}];