I have a timer which works perfectly if the timer is in the foreground. It decrements perfectly and stops at 0. However, when I tap the homebutton to go to the main screen, and then wait for the local notification to pop up, and then I tap the notification, the time interval turns into 4.2 billion (the limit for unsigned long int). Basically, it doesn't stop at 0. I'm not sure how to fix this. I tried making it a regular NSInteger and checking if the interval went below 0 but I got the same results.
-(IBAction)startTimer:(id)sender{
if (!timer) {
[startButton setTitle:@"Start" forState:UIControlStateNormal];
timer = [NSTimer scheduledTimerWithTimeInterval:1.0 target:self selector:@selector(timerAction:) userInfo:nil repeats:YES];
date = [NSDate date];
} else {
[startButton setTitle:@"Stop" forState:UIControlStateNormal];
anotherTimeInterval = testTask.timeInterval;
[timer invalidate];
timer = nil;
}
}
-(void)timerAction:(NSTimer *)t
{
NSTimeInterval interval = [[NSDate date] timeIntervalSinceDate:date];
if (testTask.timeInterval > 0){
NSError *error;
if (![self.context save:&error]) {
NSLog(@"couldn't save: %@", [error localizedDescription]);
}
NSUInteger seconds = (NSUInteger)round(anotherTimeInterval-interval);
NSString *string = [NSString stringWithFormat:@"%02u:%02u:%02u",
seconds / 3600, (seconds / 60) % 60, seconds % 60];
testTask.timeInterval = seconds;
timerLabel.text = string;
NSLog(@"%@", string);
} else {
NSLog(@"timer ended");
[self.timer invalidate];
self.timer = nil;
[self timerExpired];
}
}
-(void)applicationWillResignActive:(UIApplication *)application{
if (timer){
UILocalNotification* localNotification = [[UILocalNotification alloc] init];
localNotification.fireDate = [NSDate dateWithTimeIntervalSinceNow:testTask.timeInterval];
localNotification.alertBody = @"Time is up";
localNotification.alertAction = @"Ok";
localNotification.timeZone = [NSTimeZone defaultTimeZone];
[[UIApplication sharedApplication] scheduleLocalNotification:localNotification];
}
}
The
%02u
you're using in thestringWithFormat:
parses the value as an unsigned int.Also, and I think this is your problem, you're checking testTask.timeInterval in your
if
statement, but getting the number of seconds from theinterval
variable you get at the start of the method. So you're always checking the previous value, meaning you're always one second behind.Edit: You could do somehting like this:
That way, you check the new value instead of the old one.
Hope this helps