Search code examples
iosreactive-cocoa

ReactiveCocoa takeUntil: doesn't send completion?


I'm doing some basic signal chaining. After a button is pressed, I want to wait until loginSignal completes to do some things. The signal completes, but my subscribeCompleted: block isn't called.

Subscribing directly to next and completion on loginSignal work as expected. So why doesn't takeUntil: subscribeCompleted: work?

[[[button rac_signalForControlEvents:UIControlEventTouchUpInside] takeUntil:loginSignal] subscribeCompleted:^{
    NSLog(@"COMPLETE");
    // Do some other stuff
}];

Edit: Here's the output from logAll

2014-08-15 10:52:56.417 app[88791:60b] <RACDynamicSignal: 0x10c58a120> name:  next: <UIButton: 0x10c68a870; frame = (240 80; 40 40); opaque = NO; autoresize = TM+BM; autoresizesSubviews = NO; tag = 1103; layer = <CALayer: 0x10c6894a0>>
2014-08-15 10:52:56.417 app[88791:60b] <RACDynamicSignal: 0x10c58a120> name:  next: <UIButton: 0x10c68a870; frame = (240 80; 40 40); opaque = NO; autoresize = TM+BM; autoresizesSubviews = NO; tag = 1103; layer = <CALayer: 0x10c6894a0>>
2014-08-15 10:53:02.086 app[88791:410b] <RACDynamicSignal: 0x112e2c4b0> name:  next: 1
2014-08-15 10:53:02.087 app[88791:410b] <RACDynamicSignal: 0x10c6ea5d0> name:  next: 1
2014-08-15 10:53:02.087 app[88791:410b] <RACDynamicSignal: 0x10c6ea5d0> name:  next: 1
2014-08-15 10:53:02.088 app[88791:410b] <RACDynamicSignal: 0x10c6b8830> name:  next: 1
2014-08-15 10:53:02.089 app[88791:410b] <RACDynamicSignal: 0x10c6b8830> name:  next: 1
2014-08-15 10:53:02.089 app[88791:410b] <RACDynamicSignal: 0x10c52e570> name:  next: 1
2014-08-15 10:53:02.090 app[88791:410b] <RACDynamicSignal: 0x10c52e570> name:  next: 1

Edit 2: Here's loginSignal

RACSignal* loginSignal = [[[RACObserve(obj, loginState) distinctUntilChanged] filter:^BOOL(id value) {
    return ([value integerValue] == LOGGEDIN);
}] takeUntil:[self rac_prepareForReuseSignal]];

Solution

  • It turns out, takeUntil: is not the correct way to go about getting this behavior. Once the loginSignal fired, it caused the sendCompleted: to fire multiple times (therefore appearing not to fire?), even for buttons that had not been tapped. Better way is to flattenMap: and send the loginSignal.

    Correct version:

    [[[[[button rac_signalForControlEvents:UIControlEventTouchUpInside] flattenMap:^RACStream *(id value) {
        return loginSignal;
    }] take:1] subscribeNext:^(id value){
        // DO STUFF!!!
    }];