Cancelable timeout in Reactive Cocoa

cocoa-touch, ios, objective-c, reactive-cocoa, reactive-programming

Solution

I think, I found the solution. The trick is to merge the cancel signal into the tick signal, then take X samples. The final subscribers will receive a next event every time the tick signal ticks and completed when the 'take' is finished. Cancellation can be implemented by sending error on the cancel timer.

__block RACSubject *cancelTimer = [RACSubject subject];
RACSubscribable *tickWithCancel = [[RACSubscribable interval:1.0] merge:cancelTimer];
RACSubscribable *timeoutFiveSec = [tickWithCancel take:5];

[timeoutFiveSec subscribeNext:^(id x) {
    NSLog(@"Tick");
} error:^(NSError *error) {
    NSLog(@"Cancelled");
} completed:^{
    NSLog(@"Completed");
    [alert dismissWithClickedButtonIndex:-1 animated:YES];
}];

To activate cancel, one has to do the following.

[cancelTimer sendError:nil]; // nil or NSError

Problem

I want to implement a countdown timer using Reactive Cocoa in iOS. The timer should run for X seconds and do something in every second. The part I cannot figure out is the way I could cancel the timeout. ``` RACSubscribable *oneSecGenerator = [RACSubscribable interval:1.0]; RACDisposable *timer = [[oneSecGenerator take:5] subscribeNext:^(id x) { NSLog(@"Tick"); }]; ```

Original source