簡體   English   中英

后台任務不調用Swift中的類

[英]Background task not calling class in Swift

我有一個后台任務,應該返回一系列課程,然后將其發送到Apple Watch。 我打電話里面的任務didReceiveMessage通過WatchConnectivity

后台任務需要執行一些操作,例如打開領域數據庫,查詢結果以及訪問文檔目錄,然后將響應返回到課程字典。 當手表輸出其獲取課程數據時,邏輯似乎起作用。 問題是我不認為后台任務實際上在調用方法getWatchCourses()

DispatchQueue.global().async {

    var foundCourses = [[String : Any]]()
    let application = UIApplication.shared
    backgroundTask = application.beginBackgroundTask(withName: "app.test.getCourses") {
        let watchModel = WatchCourseModel()
        let courses = watchModel.getWatchCourses()
        print("Courses: \(courses)")
        foundCourses.append(contentsOf: courses)
    }
    replyHandler(["response": foundCourses])
    application.endBackgroundTask(backgroundTask)
    backgroundTask = UIBackgroundTaskInvalid
}

如果getWatchCourses()結果是硬編碼的,那么這也不起作用。 應用程序可以在后台執行此邏輯嗎?

值得指出的是,沒有任何文檔記錄在網上,他們總是指將簡單的文本響應發送回手表,而不是占用大量處理器資源的:(

謝謝

您正在使用尾隨閉包進行操作,該操作用於清理。 還有更多事情要在后台任務開始后立即結束,因此您的關閉將永遠不會調用。

這是后台任務如何工作的示例

 var backgroundTaskIdentifier:UIBackgroundTaskIdentifier = UIBackgroundTaskInvalid
 var updateTimer: Timer?

現在,當您開始運行示例運行計時器時,

  updateTimer = Timer.scheduledTimer(timeInterval: 0.5, target: self,
                                     selector: #selector(calculateNextNumber), userInfo: nil, repeats: true)
  // register background task
  beginBackgroundTask()

當您結束計時器時,結束后台任務; 應該總是結束后台任務而不會失敗

func beginBackgroundTask () {
    backgroundTaskIdentifier = UIApplication.shared.beginBackgroundTask(expirationHandler: { [weak self] in
      self?.endBackgroundTask() // It will call to cleanup 
    })
    assert(backgroundTaskIdentifier != UIBackgroundTaskInvalid)
  }

  func endBackgroundTask () {
    UIApplication.shared.endBackgroundTask(backgroundTaskIdentifier)
    backgroundTaskIdentifier = UIBackgroundTaskInvalid
  }

所以你的情況

  • 注冊后台任務
  • 查詢數據庫(執行所有操作)
  • 完成通話結束后台任務后

注意:還要注意蘋果給出的執行后台任務的時間限制

編輯

確保已啟用后台功能表單項目設置

嘗試像

    beginBackgroundTask()

    let watchModel = WatchCourseModel()
    let courses = watchModel.getWatchCourses()
    print("Courses: \(courses)")
    foundCourses.append(contentsOf: courses)
    endBackgroundTask()

如果查看文檔 ,將會看到完整功能的原型是beginBackgroundTask(withName:expirationHandler:)

通過尾隨閉包指定的代碼是expirationHandler如果在允許的后台執行時間用完之前不調用endBackgroundTask ,則將調用該代碼。 到期處理程序為您提供了最后的機會,可以在終止應用程序超出其后台時間之前執行任何清理操作。

由於您幾乎立即調用endBackgroundTask並從函數返回,因此不會調用過期處理程序。

您實際想要的是這樣的:

var foundCourses = [[String : Any]]()
let application = UIApplication.shared
backgroundTask = application.beginBackgroundTask(withName: "app.test.getCourses") {
DispatchQueue.global().async {
    let watchModel = WatchCourseModel()
    let courses = watchModel.getWatchCourses()
    print("Courses: \(courses)")
    foundCourses.append(contentsOf: courses)
    replyHandler(["response": foundCourses])
    application.endBackgroundTask(backgroundTask)
    backgroundTask = UIBackgroundTaskInvalid
}

這將啟動一個后台任務,然后您異步執行工作並將結果傳遞回監視並結束后台任務。

您可以通過將QOS類型用作.background來創建后台任務

DispatchQueue.global(qos: .background).async {
        //background code
        var foundCourses = [[String : Any]]()
        let application = UIApplication.shared
        backgroundTask = application.beginBackgroundTask(withName: "app.test.getCourses") {
            let watchModel = WatchCourseModel()
            let courses = watchModel.getWatchCourses()
            print("Courses: \(courses)")
            foundCourses.append(contentsOf: courses)
        }
        replyHandler(["response": foundCourses])
        DispatchQueue.main.async {
            //your main thread
        }
    }

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM