Suppose that I have a telephony application. I have a feature that I want to try calling an array of users one by one and break the sequence whenever one of the users accepts call, or when the complete operation is cancelled.
I will try to simplify it like this in pseudocode:
for(user in users) {
result = callUserCommand(user);
if(result == "accepted" || result == "cancelled") {
break;
}
}
Here, the callUserCommand
is a RACCommand
that needs to be async
. And it can actually have three return values: "accepted", "cancelled", "declined"
.
Accepted and Cancelled will break the sequence of operations and won't execute the rest. Declined, should continue with the execution of the rest of the sequence.
I tried with something like the following, but really couldn't accomplish exactly the thing I described above.
RACSignal *signal = [RACSignal concat:[users.rac_sequence map:^(User * user) {
return [self.callUserCommand execute:user];
}]];
[signal subscribeNext:^(id x) {
} error:^(NSError *error) {
} completed:^{
}];
If I understood correctly you would like to execute the sequence one by one until one of the call gets accepted or cancelled.
Maybe you could give takeUntil
or takeWhile
a try. I would write this scenario with RAC like this:
NSArray* users = @[@"decline", @"decline", @"decline", @"accept", @"decline"];
[[[[[users.rac_sequence signal]
flattenMap:^RACStream *(NSString* userAction) {
NSLog(@"Calling user (who will %@):", userAction);
// return async call signal here
return [RACSignal return:userAction];
}]
takeWhileBlock:^BOOL(NSString* resultOfCall) {
return [resultOfCall isEqualToString:@"decline"];
}]
doCompleted:^{
NSLog(@"Terminated");
}]
subscribeNext:^(NSString* userAction) {
NSLog(@"User action: %@", userAction);
}];
In the sample code above the last user who would decline the call won't be called.