I am very new to reactive cocoa and I'm still getting my head around it.
But I feel like this should be possible:
So what I'm doing is the following, but what I want to do is add the downloadImageSignal if the image search fails. (basically respond to the filter saying no)
[[[imageSearch filter:^BOOL(NSString *path) {
if (path.length > 0) {
return YES;
}
return NO;
}] map:^id(NSString *path) {
return [UIImage imageWithContentsOfFile:path];
}] subscribeNext:^(UIImage *image) {
// because I want to filter it this would never really happen. I send no if length is 0.
if (!image) { // feel like this should be done in the pipeline somewhere.
[[self signalForImageDownload:stepId] subscribeNext:^(UIImage *downloadedImage) {
[subscriber sendNext:downloadedImage];
[subscriber sendCompleted];
}];
}
else {
[subscriber sendNext:image];
[subscriber sendCompleted];
}
} error:^(NSError *error) {
NSLog(@"error %@", error);
}];
Example of the flow I'm looking for:
I take it that whole block is wrapped in a createSignal:
, hence the calls to subscriber. But that's probably not necessary. Instead of:
RACSignal *imageSignal = [RACSignal createSignal:^RACDisposable *(id<RACSubscriber>subscriber) {
[[[imageSearch filter:^BOOL(NSString *path) {
...
Just assign it to be a derived signal:
RACSignal *imageSignal = [[[imageSearch filter:^BOOL(NSString *path) {
return path.length > 0;
}] map:^id(NSString *path) {
return [UIImage imageWithContentsOfFile:path];
}] flattenMap:^(UIImage *image) {
if (image) {
return [RACSignal return:image];
} else {
return [self signalForImageDownload:stepId];
}
}];
flattenMap
is like mapping into a signal of signals and then flattening the result. Since in one of the cases you don't need to do any work, you can use return:
to create a dummy signal of just one value.
However, depending on the behavior of imageSearch
, this might not be quite what you want. This will give you one image for each imageSearch
(or more, if signalForImageDownload
sends more than one next!), but there's a way to throw out old values as soon as imageSearch
sends another value: change flattenMap
to map
followed by switchToLatest
.