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】:

好的,我找到了该任务的解决方案,该任务需要一些时间,并且在应用程序离开前台时不应被中断。 所以我们需要beginBackgroundTaskendBackgroundTask

即使应用程序不在前台,您也可以使用它来执行代码

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 applicationDidEnterBackgroundapplicationWillResignActive 没问题@IgorLantushenko 在它工作后添加您的解决方案作为答案:)

以上是关于swift ios 10 异步或后台执行代码的主要内容,如果未能解决你的问题,请参考以下文章

ios - 如何在 ios swift 中正确实现后台获取

iOS swift流媒体应用程序不在后台模式下播放音乐

即使应用程序在后台运行,如何使用 swift 在 ios 中获取位置更新

iOS:关闭应用程序时如何在后台运行代码?

ArcEngine——异步执行GP工具(Background geoprocessing)

iOS 后台任务 Swift