swift ios 10 异步或后台执行代码
Posted
技术标签:
【中文标题】swift ios 10 异步或后台执行代码【英文标题】:swift ios 10 execute code asynchronously or in the background 【发布时间】:2017-06-12 08:28:54 【问题描述】:当用户启动应用程序或完成编辑数据时,我需要更新本地通知,基本上异步方式大约需要 2-3 秒。即使应用程序离开前台,我也需要确保执行此代码。我现在拥有的:
func buildLocalNotifications()
let dq = DispatchQueue.global(qos: .userInteractive)
dq.async
//recreate the notifications
我可以从didFinishLaunchingWithOptions
调用此方法,或者当用户保存表单时,一切都像魅力一样工作,而应用程序保持活动状态超过 3-4 秒并且它当然不会阻塞 UI.. 但如果用户锁定屏幕或终止应用程序 - 此代码不会完成,也不会创建通知。如何安全地执行敏感代码?
我想到了什么 - 在执行此操作时显示加载器 - 但它会阻止用户交互
【问题讨论】:
【参考方案1】:好的,我找到了该任务的解决方案,该任务需要一些时间,并且在应用程序离开前台时不应被中断。
所以我们需要beginBackgroundTask
和endBackgroundTask
即使应用程序不在前台,您也可以使用它来执行代码
class BackgroundTaskManager
let backgroundDQ = DispatchQueue.global(qos: .background)
var backgroundUpdateTask: UIBackgroundTaskIdentifier!
init(withName: String)
self.backgroundUpdateTask = UIApplication.shared.beginBackgroundTask(withName: withName)
/* Using completion handler to know when code is done*/
func runBackgroundTask(withCode: @escaping (_ cH: @escaping () -> Void) -> Void)
backgroundDQ.async
withCode()
self.endBackgroungTask()
func endBackgroungTask()
if backgroundUpdateTask != nil && backgroundUpdateTask != UIBackgroundTaskInvalid
UIApplication.shared.endBackgroundTask(backgroundUpdateTask)
backgroundUpdateTask = UIBackgroundTaskInvalid
你可以像这样使用它
let taskManager = BackgroundTaskManager(withName: "LocalNotifications")
taskManager.doBackgroundTask() (cH) in
//Your code goes here
//Send back completion handler so system knows when to finish background task
cH()
您可以在Medium 上找到更多信息
【讨论】:
【参考方案2】:如果您想确保即使用户关闭您的应用程序也能执行您的代码,您需要在applicationWillTerminate
中调用您的函数。但是,在系统关闭您的应用程序之前,您只有大约 5 秒的时间来执行代码,因此这里不鼓励异步执行。同步执行代码也没关系,因为用户已经退出了你的应用,所以你不会阻止任何 UI 更新。
【讨论】:
首先谢谢您,将尝试与applicationWillTerminate
联系。还有问题:f.e.我在保存一些表单后开始更新通知,它几乎完成了,但随后用户终止了应用程序并从 applicationWillTerminate
开始更新 - 第一次执行怎么样?会在applicationWillTerminate
之前停止吗?
您应该对其进行测试以确定,但我不确定系统是在调用 applicationWillTerminate 之前关闭您的进程,还是在您的代码在 applicationWillTerminate 中执行时继续运行它们。但是您可以手动取消添加到 DispatchQueue 的工作项,请参阅this 答案。【参考方案3】:
尝试在后台执行你的代码
DispatchQueue.global(qos: .background).async
// your code here
【讨论】:
感谢 @Muhammed 刚才尝试使用. background
而不是 . userInteractive
并注意到当我锁定设备时 - 它也会停止,但是当解锁时 - 继续,所以看起来我的解决方案将与applicationWillTerminate
或 applicationDidEnterBackground
或 applicationWillResignActive
没问题@IgorLantushenko 在它工作后添加您的解决方案作为答案:)以上是关于swift ios 10 异步或后台执行代码的主要内容,如果未能解决你的问题,请参考以下文章
即使应用程序在后台运行,如何使用 swift 在 ios 中获取位置更新