1.
private lazy var session: URLSession = { let configuration = URLSessionConfiguration.default configuration.waitsForConnectivity = true return URLSession(configuration: configuration, delegate: self, delegateQueue: nil) }()
Listing 3
Using a delegate with a URL session data task
var receivedData: Data? func startLoad() { loadButton.isEnabled = false let url = URL(string: "https://www.example.com/")! receivedData = Data() let task = session.dataTask(with: url) task.resume() } // delegate methods func urlSession(_ session: URLSession, dataTask: URLSessionDataTask, didReceive response: URLResponse, completionHandler: @escaping (URLSession.ResponseDisposition) -> Void) { guard let response = response as? HTTPURLResponse, (200...299).contains(response.statusCode), let mimeType = response.mimeType, mimeType == "text/html" else { completionHandler(.cancel) return } completionHandler(.allow) } func urlSession(_ session: URLSession, dataTask: URLSessionDataTask, didReceive data: Data) { self.receivedData?.append(data) } func urlSession(_ session: URLSession, task: URLSessionTask, didCompleteWithError error: Error?) { DispatchQueue.main.async { self.loadButton.isEnabled = true if let error = error { handleClientError(error) } else if let receivedData = self.receivedData, let string = String(data: receivedData, encoding: .utf8) { self.webView.loadHTMLString(string, baseURL: task.currentRequest?.url) } } }
https://developer.apple.com/documentation/foundation/url_loading_system/fetching_website_data_into_memory
===============================================
1.
12.If a download task completes successfully, then the NSURLSession
object calls the task’s URLSession:downloadTask:didFinishDownloadingToURL:
method with the location of a temporary file. Your app must either read the response data from this file or move it to a permanent location before this delegate method returns.
https://developer.apple.com/documentation/foundation/nsurlsession?language=objc
https://www.jianshu.com/p/8790684782c3
2.
后台任务完成操作
在切到后台之后,Session的Delegate不会再收到,Task相关的消息,直到所有Task全都完成后,系统会调用ApplicationDelegate的application:handleEventsForBackgroundURLSession:completionHandler:回调,把通知App后台Task已经完成,这里你需要completionHandler的bloack存起来下面会用到,接着每一个后台的Task就会调用Session的Delegate中的URLSession:downloadTask:didFinishDownloadingToURL:和URLSession:task:didCompleteWithError: 。
各个Task在Session的delegate调用之后,最后会调用Session的Delegate回调URLSessionDidFinishEventsForBackgroundURLSession:。这个时候你可以调用上面保存completionHandler的bloack,告知系统你的后台任务已经完成,系统可以安全的休眠你的App。
https://blog.****.net/hxming22/article/details/79392880
https://github.com/nsscreencast/093-background-transfers
3.
AFURLSessionManager
- (void)setDidFinishEventsForBackgroundURLSessionBlock:(void (^)(NSURLSession *session))block { self.didFinishEventsForBackgroundURLSession = block; } 。。。 - (void)URLSessionDidFinishEventsForBackgroundURLSession:(NSURLSession *)session { if (self.didFinishEventsForBackgroundURLSession) { dispatch_async(dispatch_get_main_queue(), ^{ self.didFinishEventsForBackgroundURLSession(session); }); } }