2017-06-12 29 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