I have just started learning reactivecocoa. i want to perform network operation for each entry in a collection object and parse return result, mark the entry as invalid if an error is reported.
The following example illustrate the problem. urlList array is having 4 entries.2 entries generates error (generates connection closed and timeout error). so subscribe block is not notified for all the entries.
- (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 *(id<RACSubscriber> subscriber) {
[[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"];
}];
}
Output:
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."}
I want subscribeNext/Error block to be notified for all the entries in the collection,so that i can mark the entry as valid or invalid.
How to achieve it using reactive cocoa.
UPDATE
I have tried with replacing the subscription block with catch block like below. it catches only the first error event.
- (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 *(id<RACSubscriber> subscriber) {
[[[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;
}];
}
Output:
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."}
How to catch all the errors?