ReactiveCocoa - How to get one item at a time from RACSequence?

520 views Asked by At

I keep reading that RACSequences are "pull-driven". Can someone explain to me how to "pull" values out of a sequence on demand?

Say I have an array that I have turned into a signal. Then say there is another signal and when a value is sent on it, I want to get the next value out of the array sequence. How would I make that happen? This is what I have tried but it doesn't work.

RACSignal *arraySig = [@[@1, @2, @3].rac_sequence signal];
RACSubject *triggerSig = [RACSubject subject];

[[[arraySig doNext:^(id x) {
        DDLogVerbose(@"DoNext got %@ from array", x);
    }]
    sample:triggerSig]
    subscribeNext:^(id x) {
        DDLogVerbose(@"Subscriber got %@ from array", x);
    }];

[triggerSig sendNext:@"Give me data!"];

// I expect to see "Got 1 from array" printed out

EDIT: I updated the above sample so that there is a do next before the sample and a subscriber at the end.

This is what I get for output:

DoNext got 1 from array
DoNext got 2 from array
DoNext got 3 from array

No values get through to the subscriber. I think that sample is not what I want here. To me it looks like sample subscribes to the signal and immediately the values in the array get sent. However, sample blocks the values from getting through to the subscriber until the sample signal sends. My theory is that by the time the trigger signal sends, all the values in the array have been sent. Although it seems like if that were the case, the subscriber would at least get the last value that was sent, @3.

1

There are 1 answers

0
Patrick Bacon On BEST ANSWER

You should be able to accomplish this with +zip:reduce:

RACSignal *arraySig = [@[@1, @2, @3].rac_sequence signal];
RACSubject *triggerSig = [RACSubject subject];

[[RACSignal zip:@[arraySig, triggerSig] reduce:^id(id arrayVal, id triggerVal) {
    return arrayVal;
}] subscribeNext:^(id x) {
    DDLogVerbose(@"Subscriber got %@ from array", x);
}];

[triggerSig sendNext:@"Give me data!"];

The zip operation waits for values from both signals before passing both along to the reduce. So in your case, it will wait for the trigger to fire before sending the next pair of values.