如何知道后台任务是否在 swift 内完成?

How to know if a background task is finished in swift?

我一直在使用 Swift 在 Iphone 上开发应用程序。我只是新手,没有太多经验。我现在有问题。启动我的应用程序后,我将计时器用于后台进程。例如,我每 0.2 秒调用函数来检查服务器是否收到响应。这不是您认为的正确方法。现在我正在尝试学习 swift。我真正需要的是,我需要知道一个后台进程何时结束,我需要启动其他后台进程。

DispatchQueue.global(cos: .UserInteractive).async{
     //some request and parsing json
}

现在我需要知道这个任务已经完成了。我必须开始另一个任务。具体来说,我会检查所需的最新版本,然后发出登录请求,从背景中提取一些图像,然后完成动画。这就是为什么我需要知道如何知道后台线程已完成以便我可以启动其他线程。我想我应该使用串行队列吧? 再想一想,我必须检查进程是否花费了这么多时间,所以会警告用户连接。

DispatchQueueHelper.delay(byseconds: x, cos:.background){
     // will this work for killing the thread
}

您可以使用调度组来跟踪您的操作:

let dispatchGroup = DispatchGroup()
dispatchGroup.enter()
dispatchGroup.leave()
dispatchGroup.notify(queue: .main) {
    // Back on main
}

但这通常发生在您一次创建多个请求时。通常网络请求有它们自己的完成块,它会在完成时提醒您。类似于:

URLSession.shared.dataTask(with: url) {(data, response, error) in
    // Task is done
}

在您调用以执行请求的函数中,您应该将 completionBlock 保留为:

func execute(request url: URLRequest, completion: (() -> ()) {
    URLSession.shared.dataTask(with: url) {(data, response, error) in
        completion()
    }
}

您当然不应该立即调用完成,因为您要处理数据并将其发送到内部。

在 swift 5 中,他们介绍了 Result<Any, Error>,这是在您的 completionBlock completion: ((Result<Model, Error>) -> ())

中发送的好东西

另一边看起来像:

execute(request: request { result in
        switch result {
        case .success(let model):
            // Handle data
        case .failure(let error):
            // Handle error
        }
    })

您可以使用 sync 而不是 async 并在队列中添加多个任务。 这样他们就会一个接一个被执行。

另一方面,async同时运行它们,更难知道哪个完成了。