由于某种原因,我的计时器只在前台运行。我在这里寻找解决方案,但我找不到任何好的解决方案。我的计时器使用Core Data,每次减量后都会保存timeInterval。此外,我发送UILocalNotification,但这不起作用。我假设它不会发送警报视图,如果它在前台..这就是我现在拥有的:
-(IBAction)startTimer:(id)sender{
if (timer == nil) {
[startButton setTitle:@"Pause" forState:UIControlStateNormal];
timer = [NSTimer scheduledTimerWithTimeInterval:1.0 target:self selector:@selector(timerAction:) userInfo:nil repeats:YES];
} else {
[startButton setTitle:@"Resume" forState:UIControlStateNormal];
[timer invalidate];
timer = nil;
}
}
-(void)timerAction:(NSTimer *)t
{
if(testTask.timeInterval == 0)
{
if (self.timer)
{
[self timerExpired];
[self.timer invalidate];
self.timer = nil;
}
}
else
{
testTask.timeInterval--;
NSError *error;
if (![self.context save:&error]) {
NSLog(@"couldn't save: %@", [error localizedDescription]);
}
}
NSUInteger seconds = (NSUInteger)round(testTask.timeInterval);
NSString *string = [NSString stringWithFormat:@"%02u:%02u:%02u",
seconds / 3600, (seconds / 60) % 60, seconds % 60];
timerLabel.text = string;
NSLog(@"%f", testTask.timeInterval);
}
-(void)timerExpired{
UILocalNotification* localNotification = [[UILocalNotification alloc] init];
localNotification.alertBody = @"Time is up";
localNotification.alertAction = @"Ok";
localNotification.timeZone = [NSTimeZone defaultTimeZone];
[[UIApplication sharedApplication]presentLocalNotificationNow:localNotification];
}
我非常感谢让我的计时器在后台运行的一些指导(就像Apple的计时器一样)。我不确定如何使用NSDateComponents,因为即使应用程序在后台我也需要更新testTask.timeInterval ..
答案 0 :(得分:6)
UIBackgroundTaskIdentifier bgTask =0;
UIApplication *app = [UIApplication sharedApplication];
bgTask = [app beginBackgroundTaskWithExpirationHandler:^{
[app endBackgroundTask:bgTask];
}];
NSTimer *timer = [NSTimer scheduledTimerWithTimeInterval:1.0
target:self
selector:@selector(timerCountDown:)
userInfo:nil
repeats:YES];
现在使用此方法触发通知。计时器将在后台运行。
答案 1 :(得分:3)
正如Josh Caswell所写,你应该在应用程序进入后台之前保存你的计时器状态,然后当你的应用程序再次进入前台时检索它。
如果您需要在适当的时候发送本地通知,您可以在进入后台之前使用计时器的状态进行设置:
UILocalNotification *localNotification = [[UILocalNotification alloc] init];
NSDateFormatter *dateFormat = [[NSDateFormatter alloc] init];
[dateFormat setDateFormat:@"yyyyMMddHHmmss"];
NSDate *when = [dateFormat dateFromString:desiredTime];
// desiredTime -> time you want your local notification to be fired, take this from your timer before app enters the background
[dateFormat release];
localNotification.fireDate = when;
localNotification.timeZone = [NSTimeZone defaultTimeZone];
localNotification.soundName = UILocalNotificationDefaultSoundName;
localNotification.alertBody = @"Hey";
[[UIApplication sharedApplication] scheduleLocalNotification:localNotification];
[localNotification release];
编辑:在您的appDelegate中,您应该找到以下方法:
(1) - (void)applicationWillResignActive:(UIApplication *)application
(2) - (void)applicationDidEnterBackground:(UIApplication *)application
(3) - (void)applicationWillEnterForeground:(UIApplication *)application
(4) - (void)applicationDidBecomeActive:(UIApplication *)application
(5) - (void)applicationWillTerminate:(UIApplication *)application
这些内容专门用于管理应用状态发生变化时的行为。
在进入后台和恢复之前,您可以执行所需的一切。
在进入后台之前,您需要几秒钟来执行本地通知计划并保存计时器状态(例如使用NSUserDefaults
)。
之后,如果由于以下原因之一而无法在后台运行,那么Apple可能会杀死您的应用:
实现长时间运行的后台任务适用于需要更多任务的任务 要执行的执行时间,您必须请求特定的权限 在后台运行它们而不会被暂停。仅在iOS中 允许特定的应用类型在后台运行:
- 在后台播放用户可听内容的应用, 例如音乐播放器应用
- 随时向用户通知其位置信息的应用,例如导航应用
- 支持互联网协议语音(VoIP)的应用
- 需要下载和处理新内容的报亭应用
- 从外部附件接收定期更新的应用
取自here。
我建议您阅读有关后台任务的this。