0

In my current situation I can get by with doing this:

[isFooSignal subscribeNext:^(NSNumber *isFoo) {
    [isBarSignal subscribeNext:^(NSNumber *isBar) {
        if ([isFoo boolValue]) {
            if ([isBar boolValue]){
                // isFoo and isBar are both true
            }
            else {
                // isFoo is true and isBar is false
            }
        }
    }];
}];

but ideally I think I want to subscribe to both signals and be able to access both of their latest values regardless of which changed first.

Something like:

...^(NSNumber *isFoo, NSNumber *isBar) {
    NSLog(@"isFoo: %@" isFoo);
    NSLog(@"isBar: %@", isBar);
}];

How can I achieve this using ReactiveCocoa?

Paul Young
  • 1,489
  • 1
  • 15
  • 34

1 Answers1

1

You can do this with +combineLatest:reduce::

[[RACSignal
    combineLatest:@[ isFooSignal, isBarSignal ]
    reduce:^(NSNumber *isFoo, NSNumber *isBar) {
        return @(isFoo.boolValue && isBar.boolValue);
    }]
    subscribeNext:^(NSNumber *isBoth) {
        NSLog(@"both true? %@", isBoth);
    }];
Justin Spahr-Summers
  • 16,893
  • 2
  • 61
  • 79
  • Could you be more specific? My attempts to do this seem to result in having access to only one of the values. – Paul Young Feb 19 '14 at 20:34
  • thanks, I tried this but as shown at the end of the question, I need to be able to access both values. – Paul Young Feb 19 '14 at 20:45
  • FWIW I also tried accessing the values before returning in the `reduce:` block, without success. – Paul Young Feb 19 '14 at 20:49
  • One potential pitfall with `+combineLatest:` is that it doesn't send anything until _both_ inputs have. You can work around this by adding `-startWith:` to either or both of the inputs, forcing them to push an initial value through. – Justin Spahr-Summers Feb 19 '14 at 20:51
  • What I ended up doing is accessing the properties of my view model directly inside of the `subscribeNext:` block. I was expecting to be able to pass them both as arguments to a block but if that's possible it's not apparent to me how to do so. – Paul Young Feb 19 '14 at 21:25
  • Since it appears that I need to access the properties directly, is there any difference in using `merge:` instead of `combineLatest:reduce:`? – Paul Young Feb 19 '14 at 21:27
  • is there perhaps a different way to say, "when A or B changes tell me the value of A and the value of B"? – Paul Young Feb 19 '14 at 23:41
  • 1
    You can use `+combineLatest:` _without_ the `reduce:` parameter, which will pass through the combined values as a `RACTuple`. This is different from `+merge:`, which forwards events as they're sent from any input signals (not combining them in any way). – Justin Spahr-Summers Feb 19 '14 at 23:48
  • `+combineLatest:` appears to be best suited in this case. Thanks! – Paul Young Feb 20 '14 at 06:37
  • if you'd like to revise your answer I'll accept it. – Paul Young Feb 20 '14 at 06:38