在应用程序进入暂停状态之前执行后台任务

问题描述:

我正试图在我的应用程序中执行有限长度的后台任务。但是,截至目前,我的代码在应用程序暂停之前未被执行。在应用程序进入暂停状态之前执行后台任务

我遵循了不少教程,声称以下是这种方式,但显然我得到了一些错误。相关代码应贴在下面(请只问任何澄清,如果我失去了一些东西):

class Manager { 

    private var backgroundTask: UIBackgroundTaskIdentifier = UIBackgroundTaskInvalid 

    init(){ 
     // Add observer able of detecting when app will go to background 
     NotificationCenter.default.addObserver(self, selector: #selector(self.didEnterBackground(_:)), name: .UIApplicationDidEnterBackground, object: nil) 
    } 

    deinit { 
     // Observers removed when view controller is dismissed/deallocated 
     NotificationCenter.default.removeObserver(self) 
    } 

     // Routine performed when app will resign from active 
@objc private func didEnterBackground(_ notification: Notification){ 

    registerBackgroundTask() 

    // Code that needs to be executed before app is suspended ------ 
    DispatchQueue.global().sync { 

     self.isBackgrounding = true 

     self.shutdownSession() 


     self.isConnected = false 
     self.isActivated = false 
     self.activate = false 

     self.connectionManager.closeConnectionToPeripherals() 

    } 
    // ----------------------------------------------------- 
    self.endBackgroundTask() 

} 

func registerBackgroundTask() { 
    backgroundTask = UIApplication.shared.beginBackgroundTask { [weak self] in 
     self?.endBackgroundTask() 
    } 
    assert(backgroundTask != UIBackgroundTaskInvalid) 
} 

func endBackgroundTask() { 
    print("\n\n\nBackground task ended.\n\n\n") 
    UIApplication.shared.endBackgroundTask(backgroundTask) 
    backgroundTask = UIBackgroundTaskInvalid 
} 

} 

我面临着一个问题,即后台任务似乎总是执行代码之前结束。如何在应用程序被暂停之前确保我的同步块中的代码得到执行?

我不太了解“registerBackgroundTask()” - 即使互联网坚持以这种方式实现 - 因为它调用了endBackgroundTask()。

您需要将self.endBackgroundTask()呼叫转移到您的DispatchQueue区块,在self.connectionManager.closeConnectionToPeripherals()之后。

registerBackgroundTask方法不直接调用self.endBackgroundTask(),而是仅在后台任务过期时调用。通常情况下,如果您的应用在后台〜30s后没有完成任务,就会发生这种情况。

+0

我重新安排了您的建议的代码,但“后台任务结束”。仍然立即执行。我知道这个任务需要约。总共7秒,所以有些事情仍然是错误的。 它可能与我调用函数并因此被执行/启动但未在内部完成的事实有关吗? – matiastofteby

+1

是的。如果您正在调用的函数正在执行异步工作,系统可能会在您返回之前冻结您的应用程序。如果这些函数需要是异步的,那么你必须通过传递一个完成块来修改它们,并在所有返回时立即执行'endBackgroundTask'。 – ersjoh