Just starting out with ReactiveCocoa and slowly converting my current code to use it.
Right now i have a countdown to date timer done, just im not sure how to stop the timer when the countdown is done and do another action on complete.
NSTimeInterval dateInSecond = 1440855240;
self.dateUntilNextEvent = [NSDate dateWithTimeIntervalSince1970:dateInSecond];
RACSignal *countdownSignal = [[[[RACSignal interval:1 onScheduler:[RACScheduler schedulerWithPriority:RACSchedulerPriorityBackground]]
startWith:[NSDate date]] map:^id(NSDate *value) {
if([self.dateUntilNextEvent earlierDate:value] == self.dateUntilNextEvent){
//Stop "timer" and call an onComeplete method
return @"0";
}
NSUInteger flags = NSDayCalendarUnit
| NSHourCalendarUnit
| NSMinuteCalendarUnit
| NSSecondCalendarUnit;
NSDateComponents *components = [[NSCalendar currentCalendar] components:flags
fromDate:value
toDate:self.dateUntilNextEvent options:0];
return [NSString stringWithFormat:@"%02ld : %02ld : %02ld : %02ld",
(long)[components day], (long)[components hour],
(long)[components minute], (long)[components second]];
}] deliverOn:RACScheduler.mainThreadScheduler];
RAC(self.countdownLabel,text) = countdownSignal;
Any help would be appriciated, or just which direction to go in!
You can use -takeUntilBlock:
to shut down the signal when some predicate becomes true:
@weakify(self);
RAC(self.countdownLabel, text) =
[[[[[RACSignal interval:1
onScheduler:[RACScheduler schedulerWithPriority:RACSchedulerPriorityBackground]]
startWith:[NSDate date]]
takeUntilBlock:^BOOL(NSDate *date) {
@strongify(self);
return [self.dateUntilNextEvent compare:date] == NSOrderedAscending;
}]
map:^id(NSDate *date) {
// Your NSCalendar/NSString transformation here.
}]
deliverOn:RACScheduler.mainThreadScheduler];
Totally unrelated:
You also mentioned you're just getting started with ReactiveCocoa. One of the gotchas for new users is when a signal is retained by an object, but the signal is composed of blocks that make strong references to that same object.
In your -map
, you've got references to self
. The block therefore will take ownership of self
(increment its retain count), and then when the block is given to the signal, the signal takes ownership of the block, and then finally when you bind the signal to self.countdownLabel
, your self
takes ownership of the signal.
Therefore, note that in my -takeUntilBlock
I've used the @weakify/@strongify
technique. Be sure to read up on this, or you'll introduce retain cycles into your code.