Ios 在应用程序进入挂起状态之前执行后台任务

Ios 在应用程序进入挂起状态之前执行后台任务,ios,swift,background,Ios,Swift,Background,我正在尝试在我的应用程序中执行有限长度的背景任务。但是,到目前为止,我的代码在应用程序挂起之前不会执行 我已经听了很多教程,声称下面是正确的方法,但很明显我有点做错了。相关代码应张贴在下面(如果我遗漏了什么,请询问任何澄清): 我面临一个问题,后台任务似乎总是在执行代码之前结束。如何确保在应用程序挂起之前执行同步块中的代码 我也不太理解“registerBackgroundTask()”——尽管互联网坚持以这种方式实现它——因为它称之为endBackgroundTask() 您需要将您的self

我正在尝试在我的应用程序中执行有限长度的背景任务。但是,到目前为止,我的代码在应用程序挂起之前不会执行

我已经听了很多教程,声称下面是正确的方法,但很明显我有点做错了。相关代码应张贴在下面(如果我遗漏了什么,请询问任何澄清):

我面临一个问题,后台任务似乎总是在执行代码之前结束。如何确保在应用程序挂起之前执行同步块中的代码


我也不太理解“registerBackgroundTask()”——尽管互联网坚持以这种方式实现它——因为它称之为endBackgroundTask()

您需要将您的
self.endBackgroundTask()
调用移动到DispatchQueue块中,就在
self.connectionManager.closeconnectionPeripherals()之后


registerBackgroundTask
方法不会直接调用
self.endBackgroundTask()
,而只有在后台任务过期时才会调用它。通常,如果你的应用程序在后台大约30秒后仍未完成任务,就会发生这种情况。

我根据你的建议重新排列了代码,但“后台任务已结束。”仍然会立即执行。我知道这项任务总共需要大约7秒钟,所以还是有问题。这可能与我调用函数有关吗?它们是这样执行/启动的,但没有在内部完成?是的。如果您正在调用的函数正在执行异步工作,系统可能会在它们返回之前冻结您的应用程序。如果这些函数需要异步,那么您必须通过传递一个完成块来修改它们,并在所有函数返回后立即执行
endBackgroundTask
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
}

}