LoginSignup
23
25

More than 5 years have passed since last update.

Objective-Cでメソッドの引数にブロックを渡す

Last updated at Posted at 2014-04-21

例えばサーバから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];
     }];
23
25
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
23
25