I just thought, technically, successful completion is just a changing of the execution state to NO, after -executionSingals
has sent a value at least once and no error after the execution state changed to YES the last time.
Based on such a thoughts I made a category:
#import "RACCommand+ARLCompletedSignal.h"
@implementation RACCommand (ARLCompletedSignal)
- (RACSignal *)completed
{
RACSignal *executing = self.executing;
RACSignal *signals = self.executionSignals;
RACSignal *errors = self.errors;
RACSignal *startingExecution = [RACSignal combineLatest:@[executing, [signals take:1]]
reduce:^id(NSNumber *executing, id _){ return executing; }];
return [[startingExecution
ignore:@NO]
flattenMap:^RACStream *(id value) {
RACSignal *comletedOrFailed = [[executing ignore:@YES] subscribeOn:[RACScheduler scheduler]];
return [[[comletedOrFailed take:1] takeUntil:errors] map:^id(id value) { return nil; }];
}];
}
@end
Header:
@interface RACCommand (ARLCompletedSignal)
@property (nonatomic, readonly) RACSignal *completed;
@end
Here -comleted
sends nil when the command successfully finishes its operation.
Also at https://gist.github.com/slabko/546de430a16994a5da8e you can find the version, which sends YES if operation finishes successfully, or NO if not.
I tried it in some of my pretty simples cases and it worked. Please, let me know, if it doesn't work for yours.
However, I believe, in most cases, subscribing to the completion of the original signal, before you pass it to the command, is the best, "hackless" option.