OC 后台计时

OC后台计时

最近刚好遇到了后台计时的问题,这边搜罗总结一下

问题:1.程序切到后台NSTimer,GCDTimer能否继续计时?

1)未开启后台模式

如果在未开的后台模式的情况下两者都不能持续计时,在用户按home键后,程序切入后台,程序被挂起,计时器操作会停止。此时即使起是不会继续进行操作的。

方案:

通过获取前后台切换的时间差来补偿当前计时器的误差保证计时器切回前台保证稳定

2)开启了后台模式

开启了后台模式后,NSTiemr等后台任务可以继续执行,但是后台模式的持续时间只有大概10min左右。

方案1:通过设置后台模式

UIApplication*   app = [UIApplication sharedApplication];
    __block    UIBackgroundTaskIdentifier bgTask;
    bgTask = [app beginBackgroundTaskWithExpirationHandler:^{
    dispatch_async(dispatch_get_main_queue(), ^{
        if (bgTask != UIBackgroundTaskInvalid)
        {
            bgTask = UIBackgroundTaskInvalid;
        }
    });
}];
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
    dispatch_async(dispatch_get_main_queue(), ^{
        if (bgTask != UIBackgroundTaskInvalid) {
            bgTask = UIBackgroundTaskInvalid;
        }
    });
});

此时开启定时器即可在后台运行NStiemr和GCD的计时

方案2:通过计算切换前后台的时间差,在重新切回前台的时候加上时间差(有误差)如果需要很精确的计算时间不建议使用

问题2:闹钟功能能否使用GCD或者NSTimer

如果切换后台或者杀死APP 计时基本处于无用的状态,这里可以了解一下ios10的本地通知 可以通过本地通知来创建类似闹钟功能,当然不能做到像系统自带的那么完美,基本的需求可以通过这个来实现

eg:

UNUserNotificationCenter * center = [UNUserNotificationCenter currentNotificationCenter]; 

UNMutableNotificationContent * content = [[UNMutableNotificationContent alloc]init];

content.title = @"闹钟一";
content.body = @"testbody";
content.sound = [UNNotificationSound defaultSound];


UNTimeIntervalNotificationTrigger * trigger = [UNTimeIntervalNotificationTrigger triggerWithTimeInterval:60 repeats:YES];

UNNotificationRequest * reuqest = [UNNotificationRequest requestWithIdentifier:@"newalertidentifier" content:content trigger:trigger];

[center addNotificationRequest:reuqest withCompletionHandler:^(NSError * _Nullable error) {

}];