URLSession当应用程序在后台运行并被dataTask请求卡住时,数据任务块未调用。 当我打开应用程序时,将调用该块。顺便说一下,我正在使用https请求。 这是我的代码:
URLSession
dataTask
https
let request = NSMutableURLRequest(url: URL(string: url as String)!, cachePolicy: .reloadIgnoringCacheData, timeoutInterval:20) request.httpMethod = method as String request.setValue("application/x-www-form-urlencoded", forHTTPHeaderField: "Content-Type") let session = URLSession.shared let data = params.data(using: String.Encoding.utf8.rawValue) request.httpBody = data session.dataTask(with: request as URLRequest,completionHandler: {(data, response, error) -> Void in if error == nil { do { let result = try JSONSerialization.jsonObject(with: data!, options: JSONSerialization.ReadingOptions.mutableContainers) print(result) completionHandler(result as AnyObject?,nil) } catch let JSONError as NSError{ completionHandler(nil,JSONError.localizedDescription as NSString?) } } else{ completionHandler(nil,error!.localizedDescription as NSString?) } }).resume()
当应用程序处于活动状态时,可以完美运行。我的代码有什么问题吗?请指出我
如果要在应用程序不再处于前台状态后继续下载,则必须使用后台会话。在后台下载文件中概述了后台会话的基本限制,主要包括:
使用基于委托的URLSession背景URLSessionConfiguration。
URLSessionConfiguration
仅使用上传和下载任务,没有完成处理程序。
在iOS中,实施application(_:handleEventsForBackgroundURLSession:completionHandler:)应用程序委托,保存完成处理程序并启动后台会话。
application(_:handleEventsForBackgroundURLSession:completionHandler:)
实现urlSessionDidFinishEvents(forBackgroundURLSession:)你的URLSessionDelegate,呼吁救完成处理程序,让OS知道你在做处理后台请求完成。
urlSessionDidFinishEvents(forBackgroundURLSession:)
URLSessionDelegate
因此,将其组合在一起:
func startRequest(for urlString: String, method: String, parameters: String) { let url = URL(string: urlString)! var request = URLRequest(url: url, cachePolicy: .reloadIgnoringCacheData, timeoutInterval: 20) request.httpMethod = method request.setValue("application/x-www-form-urlencoded", forHTTPHeaderField: "Content-Type") request.httpBody = parameters.data(using: .utf8) BackgroundSession.shared.start(request) }
哪里
class BackgroundSession: NSObject { static let shared = BackgroundSession() static let identifier = "com.domain.app.bg" private var session: URLSession! #if !os(macOS) var savedCompletionHandler: (() -> Void)? #endif private override init() { super.init() let configuration = URLSessionConfiguration.background(withIdentifier: BackgroundSession.identifier) session = URLSession(configuration: configuration, delegate: self, delegateQueue: nil) } func start(_ request: URLRequest) { session.downloadTask(with: request).resume() } } extension BackgroundSession: URLSessionDelegate { #if !os(macOS) func urlSessionDidFinishEvents(forBackgroundURLSession session: URLSession) { DispatchQueue.main.async { self.savedCompletionHandler?() self.savedCompletionHandler = nil } } #endif } extension BackgroundSession: URLSessionTaskDelegate { func urlSession(_ session: URLSession, task: URLSessionTask, didCompleteWithError error: Error?) { if let error = error { // handle failure here print("\(error.localizedDescription)") } } } extension BackgroundSession: URLSessionDownloadDelegate { func urlSession(_ session: URLSession, downloadTask: URLSessionDownloadTask, didFinishDownloadingTo location: URL) { do { let data = try Data(contentsOf: location) let json = try JSONSerialization.jsonObject(with: data) print("\(json)") // do something with json } catch { print("\(error.localizedDescription)") } } }
iOS应用程序委托执行以下操作:
func application(_ application: UIApplication, handleEventsForBackgroundURLSession identifier: String, completionHandler: @escaping () -> Void) { BackgroundSession.shared.savedCompletionHandler = completionHandler }