Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Perform action on the hour, every hour, with ReactiveCocoa

Trying to follow the best practices of ReactiveCocoa to update my UI on the hour, every hour. This is what I've got:

NSDateComponents *components = [[[NSCalendar sharedCalendar] calendar] components:NSMinuteCalendarUnit fromDate:[NSDate date]];
// Generalization, I know (not every hour has 60 minutes, but bear with me).
NSInteger minutesToNextHour = 60 - components.minute;

RACSubject *updateEventSignal = [RACSubject subject];
[updateEventSignal subscribeNext:^(NSDate *now) {
    // Update some UI
}];

[[[RACSignal interval:(60 * minutesToNextHour)] take:1] subscribeNext:^(id x) {
    [updateEventSignal sendNext:x];
    [[RACSignal interval:3600] subscribeNext:^(id x) {
        [updateEventSignal sendNext:x];
    }];
}];

This has some obvious flaws: manual subscription and sending, and it just "feels wrong." Any ideas on how to make this more "reactive"?

like image 505
Ash Furrow Avatar asked May 13 '13 13:05

Ash Furrow


1 Answers

You can do this using completely vanilla operators. It's just a matter of chaining the two intervals together while still passing through both of their values, which is exactly what -concat: does.

I would rewrite the subject as follows:

RACSignal *updateEventSignal = [[[RACSignal
    interval:(60 * minutesToNextHour)]
    take:1]
    concat:[RACSignal interval:3600]];

This may not give you super ultra exact precision (because there might be a minuscule hiccup between the two signals), but it should be Good Enough™ for any UI work.

like image 197
Justin Spahr-Summers Avatar answered Oct 07 '22 16:10

Justin Spahr-Summers