我使用此代码每隔X分钟执行一次函数:
- (void)executeEveryOneMinute
{
[self myFunction];
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(60 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
[self executeEveryOneMinute];
});
}
当应用处于前台时,它可以正常工作
但是,当应用程序进入后台时,它将不再起作用
当我再次将应用程序返回到前台时,它会执行一次函数
并继续每分钟呼叫功能。
那么如何让它在后台工作呢?
答案 0 :(得分:4)
有关可能性的讨论,请参阅iOS App Programming Guide: App States and Multitasking的后台执行和多任务部分。例如,您可以让应用程序在后台运行几分钟,以完成一些有限长度的任务。或者,如果它正在执行一个非常特殊的功能列表(引自上述文档),您可以继续在后台运行该应用程序更长的时间段:
- 在后台播放用户可听内容的应用,例如音乐播放器应用
- 在后台录制音频内容的应用。
- 随时向用户通知其位置信息的应用,例如导航应用
- 支持互联网协议语音(VoIP)的应用
- 需要定期下载和处理新内容的应用
- 从外部附件接收定期更新的应用
实施这些服务的应用必须声明其支持的服务,并使用系统框架来实现这些服务的相关方面。声明服务可以让系统知道您使用哪些服务,但在某些情况下,系统框架实际上会阻止您的应用程序被暂停。
但是,iOS电池/电源管理的基本设计原则是随机应用程序不能(也不应该)继续在后台运行。如果您正在分享您正在尝试做的事情(即,您在executeEveryOneMinute
方法中正在做什么),我们可以就如何实现所需效果提供建议。
如果您尝试在后台继续上传,在iOS 7及更高版本中,您应该考虑将NSURLSession
与后台会话配置[NSURLSessionConfiguration backgroundSessionConfiguration:identifier]
一起使用;有类似的方法iOS 8)。这将继续尝试上传(自动,无需您的进一步干预),不仅在您的应用程序离开前台后,甚至在应用程序终止后(例如由于内存压力或崩溃)。 AFNetworking提供基于NSURLSession
的类AFURLSessionManager
,它支持此类(虽然它不是基于NSOperation
)。通过这种方式,您可以享受后台上传,但符合Apple关于后台操作的指导原则,特别是电池影响不如每60秒重试一次。
我建议你参考WWDC 2013视频What’s New in Foundation Networking的后半部分,它展示了这个过程(他们正在进行下载,但上传的想法是一样的。)
答案 1 :(得分:0)
计时器适用于主线程。当应用程序进入后台时,其定时器将变为无效。因此,当应用程序进入后台时,你不能这样做。
答案 2 :(得分:0)
您无法在计时器的帮助下执行此操作,因为它将在后台无效。您可以尝试检查this。
答案 3 :(得分:0)
您应该使用后台任务来实现您想要的目标
UIApplication* app = [UIApplication sharedApplication];
task = [app beginBackgroundTaskWithExpirationHandler:^{
[app endBackgroundTask:task];
task = UIBackgroundTaskInvalid;
}];
// Start the long-running task and return immediately.
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
// Do the work associated with the task.
NSLog(@"Started background task timeremaining = %f", [app backgroundTimeRemaining]);
if (connectedToNetwork) {
// do work son...
}
[app endBackgroundTask:task];
task = UIBackgroundTaskInvalid;
});