【问题标题】:swift ios 10 execute code asynchronously or in the backgroundswift ios 10 异步或后台执行代码
【发布时间】: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.. 但如果用户锁定屏幕或终止应用程序 - 此代码不会完成,也不会创建通知。如何安全地执行敏感代码? 我想到了什么 - 在执行此操作时显示加载器 - 但它会阻止用户交互

【问题讨论】:

    标签: ios swift


    【解决方案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 在它工作后添加您的解决方案作为答案:)
      猜你喜欢
      • 1970-01-01
      • 2017-09-25
      • 1970-01-01
      • 1970-01-01
      • 2013-07-14
      • 2018-01-25
      • 2019-01-28
      • 1970-01-01
      相关资源
      最近更新 更多