Reputation: 22289
Consider the following snippet:
- (RACSignal *)startRouting {
...
}
- (RACSignal *)updateRoutingWithSession:(NSString *)session {
...
}
- (RACSignal *)fetchFlights {
return [[self startRouting] flattenMap:^RACStream *(NSString *session) {
return [[[[self updateRoutingWithSession:session]
delay:2.0f]
repeat]
takeUntilBlock:^BOOL(RACTuple *operationAndResponse) {
AFHTTPRequestOperation *operation = [operationAndResponse first];
NSDictionary *response = [operationAndResponse second];
return [operation isCancelled] || 100 == [response[kPercentComplete] intValue];
}];
}];
}
What's happening here is that startRouting
returns a RACSignal
which sends a session ID.
updateRoutingWithSession:
returns a RACSignal
which sends an NSDictionary
looking including a PercentComplete
attribute. There's a two second delay between polls.
fetchFlights
will run until updateRoutingWithSession:
has a PercentComplete
of 100.
My issue here is that the very last sendNext:
, where the takeUntilBlock
returns true
, doesn't reach the RACSubscriber
.
What am I missing?
Upvotes: 3
Views: 2687
Reputation: 22289
I found this in the world of RX. This is commonly solved by merging two signals. One that takes the repeated source until the the predicate is true. And the other that skips while the predicate is true.
This looks something like this
BOOL (^finished)(id _) = ^BOOL(id _) {
return predicate; // BOOLean here
}
// You want a multicast signal, because multiple signals will subscribe to the source.
// Multicasting it means that you won't get repeated api-requests, in this case.
RACMulticastConnection *source = [[theSignal repeat] publish];
RACSignal *whileNotDone = [source.signal takeUntilBlock:finished];
RACSignal *whenDone = [[source.signal skipUntilBlock:finished] take:1];
RACSignal *merged = [RACSignal merge:@[whileNotDone, whenDone]];
[source connect]; // Needed for a multicast signal to initiate.
The merged
signal will sendNext
every next
in source
including the very last one. Then sendCompleted
.
Some references from the world of RX:
Upvotes: 2
Reputation: 16780
To clarify: your problem is that the next
that triggers the completion is not sent out? takeUntilBlock
will propagate the nexts until the predicate is NO. (documentation) Therefore, the last next
will not be sent. But you can subscribe to completion
which should happen in this case.
Upvotes: 1