First you need a wrapper method that performs your async operation, which will return a signal. Suppose an async operation accepts a termination block. Of the sounds of this, you do not need values, you want side effects, and in this case, the signal does not send values, it only ends.
- (RACSignal *)asyncOperation { return [RACSignal createSignal:^RACDisposable * (id<RACSubscriber> subscriber) { [self asyncOperationWithCompletion:^{ [subscriber sendCompleted]; }]; return nil; // `nil` means there no way to cancel. }]; }
EDIT: thanks to Justin Spar-Summers comment, itβs a lot easier to use a chain of operations here:
RACSignal *signal = [RACSignal concat:[array.rac_sequence map:^(id entity) { return [entity asyncOperation]; }]];
The ReactiveCocoa +concat: operator accepts a set of signals and subscribes to the signals one at a time, waiting for the completion of one signal before subscribing to its successor. Using -rac_sequence here is intended to map entities to operational signals.
In this context, using +concat: achieves the same effect as the -then: chain from my original answer below.
In the RAC shell, the solution should start with an empty signal and build a chain by iterating over objects and assembling operations using -then: Operation -then: Essentially expects the previous operation to complete before the next.
RACSignal *signal = [RACSignal empty]; for (id entity in array) { signal = [signal then:^{ return [entity asyncOperation]; }]; } [signal subscribeCompleted:^{ // At this point, all operations have completed }];
At this point you have:
[[[[RACSignal empty] then:^{ return [entity1 asyncOperation]; }] then:^{ return [entity2 asyncOperation]; }] // ... then:^{ return [entityN asyncOperation]; }]
ReactiveCocoa has useful documentation and very well-documented headers, both of which were very valuable to me when I was new.
Dave lee
source share