How to wait for all tasks of an NSURLSession to complete?

醉酒当歌 提交于 2020-06-16 07:48:37

问题


Why is NSURLSession operation queue empty after creating and resuming an NSURLSessionTask?

Is there a way to tell if an NSURLSession has tasks pending?

The goal is to wait for multiple tasks to complete, but this doesn't work:

NSURLSessionUploadTask *uploadTask = [self.session uploadTaskWithStreamedRequest:request];
[uploadTask resume];
// this prints "0"
NSLog(self.session.delegateQueue.operationCount)
// this returns immediately instead of waiting for task to complete
[self.session.delegateQueue waitUntilAllOperationsAreFinished];

回答1:


I found a solution that avoids invalidating the session, using the suggested DispatchGroup.

(answer is in Swift, while question is in ObjC ... but it's the same logic)

Note that when using, uploadTaskWithStreamedRequest:, we need to implement an URLSessionTaskDelegate and func urlSession(_ session: URLSession, task: URLSessionTask, didCompleteWithError error: Error?). So, to simplify the answer, I will demonstrate the use of DispatchGroup with uploadTaskWithRequest:from:completionHandler:.

// strong reference to the dispatch group
let dispatchGroup = DispatchGroup()

func performManyThings() {
    for _ in 1...3 {
        let request = URLRequest(url: URL(string: "http://example.com")!)
        dispatchGroup.enter()
        let uploadTask = self.session.uploadTask(with: request, from: nil) { [weak self] _, _, _ in
            self?.dispatchGroup.leave()
        }
        uploadTask.resume()
    }
    dispatchGroup.notify(queue: .main) {
        // here, all the tasks are completed
    }
}



回答2:


It's very easy as long as you don't care about reusing the session and don't mind doing things asynchronously:

  • Call finishTasksAndInvalidate on the session.
  • Implement the URLSession:didBecomeInvalidWithError: method in your session delegate to do whatever work you need to do after the last task finishes.

That said, the problem with your code above is that the session doesn't have any operations until it starts the first fetch, which can't happen as long as your code is blocking the run loop. You generally should not attempt to use NSURLSession synchronously. It is almost always the wrong way to solve things. :-)



来源:https://stackoverflow.com/questions/40883042/how-to-wait-for-all-tasks-of-an-nsurlsession-to-complete

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!