【问题标题】:How would I make my timer run in the background and then send a local notification?如何让我的计时器在后台运行,然后发送本地通知?
【发布时间】:2013-08-03 23:06:52
【问题描述】:

由于某种原因,我的计时器只在前台运行。我在这里搜索了解决方案,但找不到任何好的解决方案。我的计时器使用核心数据,每次递减后都会保存我的 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..

【问题讨论】:

标签: iphone ios objective-c nstimer uilocalnotification


【解决方案1】:
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];

现在使用此方法触发您的通知。计时器将在后台运行。

【讨论】:

  • 你如何快速做到这一点?
【解决方案2】:

正如 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,了解后台任务。

【讨论】:

  • 你会在哪里实现它以便在进入后台之前安排好它?
  • 看看我的编辑!!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-03-30
  • 2019-11-25
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多