我的Swift应用程序即使在后台也需要定期运行一段代码。做到这一点的最佳方法是什么?
我尝试了DispatchQueue.global(qos: .background).async
,但没有成功
新尝试:
我将此添加到了我的ViewController:
private var time: Date?
private lazy var dateFormatter: DateFormatter = {
let formatter = DateFormatter()
formatter.dateStyle = .short
formatter.timeStyle = .long
return formatter
}()
func fetch(_ completion: () -> Void) {
time = Date()
completion()
}
并将其发送到我的AppDelegate
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
UIApplication.shared.setMinimumBackgroundFetchInterval(UIApplicationBackgroundFetchIntervalMinimum)
// Override point for customization after application launch.
return true
}
func application(_ application: UIApplication, performFetchWithCompletionHandler completionHandler: @escaping (UIBackgroundFetchResult) -> Void) {
if let tabBarController = window?.rootViewController as? UITabBarController,
let viewControllers = tabBarController.viewControllers
{
for viewController in viewControllers {
if let fetchViewController = viewController as? ViewController {
fetchViewController.fetch {
completionHandler(.newData)
print("fired")
}
}
}
}
}
,然后在completionHandler(.newData)
上设置一个断点。
但是,当我运行该应用程序时,断点永远不会触发。并且打印语句从未执行。
答案 0 :(得分:1)
iOS不允许您的应用在后台运行时随时随地运行进程。首次进入后台时,您将有短时间(大约几分钟)执行一些任务,然后再停止。
然后,您需要使用后台获取功能定期获取应用程序的新信息。
Ray Wenderlich网站RayWenderlich - Background modes上有关于iOS支持的各种背景模式的很好的教程。
还有一个guide on Apples developer portal,说明了在后台运行应用程序时您可以做什么和不能做什么。
执行长期运行的任务
对于需要更多执行时间才能实现的任务,您必须请求特定权限才能在后台运行它们而不暂停它们。在iOS中,只允许特定的应用类型在后台运行:
- 在后台播放用户可听内容的应用,例如音乐播放器应用
- 在后台录制音频内容的应用
- 始终让用户了解其位置的应用程序,例如导航应用程序
- 支持互联网协议语音(VoIP)的应用
- 需要定期下载和处理新内容的应用
- 从外部附件中定期接收更新的应用
实现这些服务的应用程序必须声明其支持的服务,并使用系统框架来实现这些服务的相关方面。声明服务可使系统知道您使用的服务,但在某些情况下,实际上是系统框架阻止了您的应用程序被挂起。
更新:
首先,我不会将刷新代码放在ViewController中,在后台获取操作期间,VC可能不在内存中。创建一个单独的类或用于获取和存储数据的类,然后在ViewControllers viewWillAppear
函数上加载可用的最新数据。
要测试后台提取操作,请在xcode中从菜单中选择“调试”,然后选择“模拟后台提取”。它将启动应用程序并调用performFetchWithCompletionHandler
函数。