2017-06-12 30 views
1

当用户启动应用程序或完成编辑数据我需要更新本地通知,基本上它需要大约2-3秒的异步方式。我需要确保即使应用程序离开前景,该代码也会执行。我现在拥有的一切:swift ios 10异步或在后台执行代码

func buildLocalNotifications() 
    let dq = DispatchQueue.global(qos: .userInteractive) 
    dq.async { 
     //recreate the notifications 
    } 
} 

我可以从didFinishLaunchingWithOptions调用此方法,或者当用户保存的形式,一切工作就像一个魅力,同时保持应用程序的更多然后3-4秒,其不堵,当然UI活跃..但是,如果用户锁定屏幕或终止应用程序 - 此代码获胜; t完成并且不会创建通知。如何安全执行敏感代码? 我的脑海里出现了什么 - 在执行此操作时出现一个加载程序 - 但它会阻止用户交互

回答

0

好吧,我发现这需要一定的时间,当应用前景留下不应中断任务的解决方案。 所以我们需要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

0

如果要确保即使用户关闭了您的应用程序,也要执行代码,您需要致电你的功能在applicationWillTerminate。但是,在系统关闭应用程序之前,您只需要约5秒钟的时间来执行代码,因此不鼓励异步执行。如果您同步执行代码也没关系,因为用户已经退出了您的应用程序,所以您不会阻止任何UI更新。

+0

首先谢谢你,会用'applicationWillTe rminate'。还有问题:f.e.我在保存一些表单并开始更新后开始更新通知,但随后用户终止了应用程序,并从“applicationWillTerminate”开始更新 - 第一次执行的情况如何?它会在'applicationWillTerminate'之前停止吗? –

+0

您应该测试一下,但我不确定在调用applicationWillTerminate之前系统是否关闭了您的进程,或者是否在applicationWillTerminate中执行代码时继续运行它们。但是您可以手动取消添加到DispatchQueue的工作项目,请参阅[this](https://stackoverflow.com/a/38372384/4667835)答案。 –

-1

尝试EXCUTE你的代码在后台

DispatchQueue.global(qos: .background).async { 
     // your code here 
    } 
+1

感谢@穆罕默德刚刚尝试使用'。背景'而不是'。 userInteractive',并注意到当我锁定设备 - 它也停止,但是当解锁 - 继续,所以看起来像我的解决方案将与'applicationWillTerminate'或'applicationDidEnterBackground'或'applicationWillResignActive' –

+0

没问题@IgorLantushenko它工作后添加您的解决方案作为回答:) – Muhammed