ソースコードがヘッダやコメントを入れても100行にも満たない無駄の無いコード。それでいて十分な機能。
ここでいうシーケンサとは、あらかじめ登録した複数の処理を順番に実行する仕組みのこと。ネットワークアクセスやユーザインタラクションは基本非同期な処理になるが、特定の順番で同期的に処理を行いたい場合がある。シーケンサはそんな用途で利用できる。
単純な例
Sequencer *sequencer = [[Sequencer alloc] init]; [sequencer enqueueStep:^(id result, SequencerCompletion completion) { NSLog(@"This is the first step"); completion(nil); }]; [sequencer enqueueStep:^(id result, SequencerCompletion completion) { NSLog(@"This is another step"); completion(nil); }]; [sequencer enqueueStep:^(id result, SequencerCompletion completion) { NSLog(@"This step is going to do some async work..."); int64_t delayInSeconds = 2.0; dispatch_time_t popTime = dispatch_time(DISPATCH_TIME_NOW, delayInSeconds * NSEC_PER_SEC); dispatch_after(popTime, dispatch_get_main_queue(), ^(void){ NSLog(@"finished the async work."); completion(nil); }); }]; [sequencer enqueueStep:^(id result, SequencerCompletion completion) { NSLog(@"This is the last step"); completion(nil); }]; [sequencer run];completionの引数が次のステップの引数 result として渡っていく。
ネットワークアクセスの例
Sequencer *sequencer = [[Sequencer alloc] init]; [sequencer enqueueStep:^(id result, SequencerCompletion completion) { NSURL *url = [NSURL URLWithString:@"https://alpha-api.app.net/stream/0/posts/stream/global"]; NSURLRequest *request = [NSURLRequest requestWithURL:url]; AFJSONRequestOperation *operation = [AFJSONRequestOperation JSONRequestOperationWithRequest:request success:^(NSURLRequest *request, NSHTTPURLResponse *response, id JSON) { completion(JSON); } failure:nil]; [operation start]; }]; [sequencer enqueueStep:^(NSDictionary *feed, SequencerCompletion completion) { NSArray *data = [feed objectForKey:@"data"]; NSDictionary *lastFeedItem = [data lastObject]; NSString *cononicalURL = [lastFeedItem objectForKey:@"canonical_url"]; NSURLRequest *request = [NSURLRequest requestWithURL:[NSURL URLWithString:cononicalURL]]; AFHTTPRequestOperation *operation = [[AFHTTPRequestOperation alloc] initWithRequest:request]; [operation setCompletionBlockWithSuccess:^(AFHTTPRequestOperation *operation, id responseObject) { completion(responseObject); } failure:nil]; [operation start]; }]; [sequencer enqueueStep:^(NSData *htmlData, SequencerCompletion completion) { NSString *html = [[NSString alloc] initWithData:htmlData encoding:NSUTF8StringEncoding]; NSLog(@"HTML Page: %@", html); completion(nil); }]; [sequencer run];最初のステップでJSONを取得し、次にURL情報から HTMLを取得。最後にそれをログに表示。シーケンサを使うとデリゲートチェーンやblocksの多段ネストの必要が無くなり見通し良いコードが書ける。なかなかいい感じ。