Reputation: 167
I have an event that I need to schedule at the top of every hour (6am, 7am, 8am, etc). I was considering chaining performselectors withDelays together but that just seems pretty janky. Scheduling a timer would seem like the logical step however the timer the trick is that it would have to be for the TOP of every hour.
For instance, if I started at 3:48, i would expect the event to execute at 4:00, then again at 5:00 and so on, not 4:48 and 5:48.
Any suggestions?
Upvotes: 1
Views: 795
Reputation: 578
The first trick is to get the date you want. Here is an example of something like what you might need:
-(NSDate*)dateAtHour:(NSInteger)hour {
NSDate *localDate = [self toLocal];
NSDateComponents *comps = [[NSCalendar currentCalendar]
components:NSYearCalendarUnit|NSMonthCalendarUnit|NSDayCalendarUnit
fromDate:localDate];
comps.hour = hour;
comps.minute = 0;
comps.second = 0;
NSCalendar *gregorian = [[[NSCalendar alloc] initWithCalendarIdentifier:NSGregorianCalendar] autorelease];
NSDate *date = [gregorian dateFromComponents:comps];
return [date toUTC];
}
-(NSDate *) toLocal {
NSTimeZone *tz = [NSTimeZone localTimeZone];
NSInteger seconds = [tz secondsFromGMTForDate: self];
return [NSDate dateWithTimeInterval: seconds sinceDate: self];
}
-(NSDate *) toUTC {
NSTimeZone *tz = [NSTimeZone timeZoneWithName:@"UTC"];
NSInteger seconds = [tz secondsFromGMTForDate: self];
return [NSDate dateWithTimeInterval: seconds sinceDate: self];
}
Then you just need to schedule an NSTimer for a specific date/time:
- (id)initWithFireDate:(NSDate *)date interval:(NSTimeInterval)seconds target:(id)target selector:(SEL)aSelector userInfo:(id)userInfo repeats:(BOOL)repeats
However, your app could be in the background. It's not clear what you'd expect in that case, but I'm assuming you want this hourly thing to happen while the app is in the foreground. In that case, set the timer up in one of the "launch" methods of the app delegate.
Upvotes: 2
Reputation: 18487
Scheduling selectors in this manner would not be good. You could instead schedule a local notification. This would give you the ability to schedule events even though your application is backgrounded.
UILocalNotification *notification = [[UILocalNotification alloc] init];
notification.fireDate = [NSDate dateWithTimeIntervalSince1970:1373050800];
notification.userInfo = @{@"key" : @"some contextual info on what to do"};
notification.alertBody = @"Hello, it's 2pm!";
notification.alertAction = @"Details";
[[UIApplication sharedApplication] scheduleLocalNotification:notification];
Upvotes: 3