我刚刚开始学习reactivecocoa.我想对集合对象中的每个条目执行网络操作并解析返回结果,如果报告错误,则将该条目标记为无效.
以下示例说明了该问题.urlList数组有4个条目.2个条目生成错误(生成连接关闭和超时错误).因此不会通知所有条目的订阅块.
- (RACSignal *)processStationList { NSArray *urlList = @[@"http://66.55.93.205/listen.pls",@"http://84.20.77.50:8000/listen.pls",@"http://valekalter.serverroom.us:9264/listen.pls", @"http://66.55.93.205:8080/listen.pls"]; return [RACSignal createSignal:^RACDisposable *(idsubscriber) { [[urlList.rac_sequence.signal flattenMap:^RACStream *(NSString *urlString) { NSLog(@"flatten map %@",urlString); return [self fetchStationURLListForStation:urlString]; }] subscribeNext:^(id x) { NSLog(@"suscribe next %@",x); [subscriber sendNext:x]; } error:^(NSError *error) { NSLog(@"suscribe error %@",error); [subscriber sendNext:nil]; } completed:^{ NSLog(@"completed"); [subscriber sendCompleted]; }]; return nil; }]; } - (RACSignal *)fetchStationURLListForStation:(NSString *)urlString { NSURL *url = [NSURL URLWithString:urlString]; NSURLRequest *urlRequest = [NSURLRequest requestWithURL:url]; return [[NSURLConnection rac_sendAsynchronousRequest:urlRequest] map:^(RACTuple *value) { // for simplicity i have commented the following method which parses the .pls data to extract the // URL List and returing hard coded URL list // return [self processStationURLData:[value second]]; return @[@"http://66.55.93.205",@"http://66.55.93.205"]; }]; }
输出:
2014-01-27 10:49:27.108 Playground[6566:1303] flatten map http://66.55.93.205/listen.pls 2014-01-27 10:49:27.112 Playground[6566:1303] flatten map http://84.20.77.50:8000/listen.pls 2014-01-27 10:49:27.120 Playground[6566:1303] flatten map http://valekalter.serverroom.us:9264/listen.pls 2014-01-27 10:49:27.121 Playground[6566:1303] flatten map http://66.55.93.205:8080/listen.pls 2014-01-27 10:49:27.641 Playground[6566:3603] suscribe next ( "http://66.55.93.205:80/" ) 2014-01-27 10:49:27.641 Playground[6566:3603] suscribe next ( "http://66.55.93.205:8080/" ) 2014-01-27 10:50:27.161 Playground[6566:4103] suscribe error Error Domain=NSURLErrorDomain Code=-1001 "The request timed out." UserInfo=0x8b6efe0 {NSErrorFailingURLStringKey=http://valekalter.serverroom.us:9264/listen.pls, NSErrorFailingURLKey=http://valekalter.serverroom.us:9264/listen.pls, NSLocalizedDescription=The request timed out., NSUnderlyingError=0x8b6e520 "The request timed out."}
我希望subscribeNext/Error块被通知集合中的所有条目,以便我可以将条目标记为有效或无效.
如何使用活性可可来实现它.
UPDATE
我试过用下面的catch块替换订阅块.它只捕获第一个错误事件.
- (RACSignal *)processStationList { NSArray *urlList = @[@"http://66.55.93.205/listen.pls",@"http://84.20.77.50:8000/listen.pls",@"http://valekalter.serverroom.us:9264/listen.pls", @"http://66.55.93.205:8080/listen.pls"]; return [RACSignal createSignal:^RACDisposable *(idsubscriber) { [[[urlList.rac_sequence.signal flattenMap:^RACStream *(NSString *urlString) { NSLog(@"flatten map %@",urlString); return [self fetchStationURLListForStation:urlString]; }] catch:^RACSignal *(NSError *error) { NSLog(@"catch %@",error); return [RACSignal empty]; }] subscribeNext:^(id x) { NSLog(@"subscribe next %@",x); }]; return nil; }]; }
输出:
2014-01-27 10:55:45.801 Playground[6648:1303] flatten map http://66.55.93.205/listen.pls 2014-01-27 10:55:45.806 Playground[6648:1303] flatten map http://84.20.77.50:8000/listen.pls 2014-01-27 10:55:45.814 Playground[6648:1303] flatten map http://valekalter.serverroom.us:9264/listen.pls 2014-01-27 10:55:45.814 Playground[6648:1303] flatten map http://66.55.93.205:8080/listen.pls 2014-01-27 10:55:46.401 Playground[6648:3603] subscribe next ( "http://66.55.93.205:8080/" ) 2014-01-27 10:55:46.402 Playground[6648:3603] subscribe next ( "http://66.55.93.205:80/" ) 2014-01-27 10:55:57.728 Playground[6648:5007] catch Error Domain=NSURLErrorDomain Code=-1004 "Could not connect to the server." UserInfo=0x8b61730 {NSErrorFailingURLStringKey=http://valekalter.serverroom.us:9264/listen.pls, NSErrorFailingURLKey=http://valekalter.serverroom.us:9264/listen.pls, NSLocalizedDescription=Could not connect to the server., NSUnderlyingError=0x8b60f70 "Could not connect to the server."}
如何捕捉所有错误?