在后台不调用请求块的URLSession.datatask

当应用程序处于后台时, 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() 

当应用程序处于活动状态时完美工作。 我的代码有什么问题吗? 请指点我

如果您希望在应用程序不在前台后进行下载,则必须使用后台会话。 后台会话的基本约束在“ URL会话编程指南:使用NSURLSession:后台传输注意事项”中概述,主要是:

  1. 使用基于委托的URLSession和后台URLSessionConfiguration

  2. 只使用上传和下载任务,没有完成处理程序。

  3. 在应用程序委托中实现application(_:handleEventsForBackgroundURLSession:completionHandler:) ,保存完成处理程序并开始后台会话。

    在你的URLSessionDelegate实现urlSessionDidFinishEvents(forBackgroundURLSession:) ,调用保存的完成处理程序让O​​S知道你已经完成了处理后台请求的完成。

所以,一起拉:

 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! var savedCompletionHandler: (() -> Void)? 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 { func urlSessionDidFinishEvents(forBackgroundURLSession session: URLSession) { DispatchQueue.main.async { self.savedCompletionHandler?() self.savedCompletionHandler = nil } } } 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)") } } } 

而应用程序的代表:

 func application(_ application: UIApplication, handleEventsForBackgroundURLSession identifier: String, completionHandler: @escaping () -> Void) { BackgroundSession.shared.savedCompletionHandler = completionHandler } 
  [URLSessionDownloadTask setDownloadTaskDidWriteDataBlock:^(NSURLSession *session, NSURLSessionDownloadTask *downloadTask, int64_t bytesWritten, int64_t totalBytesWritten, int64_t totalBytesExpectedToWrite) { CGFloat percentDone = (double)(totalBytesWritten)/(double)totalBytesExpectedToWrite; [SVProgressHUD showWithStatus:[NSString stringWithFormat:@"%.2f%%",percentDone*100]]; }]; [downloadTask resume]; 

//如图所示应用

/ ********************* / 在这里输入图像说明

你需要一个后台会话。 根据Apple文档的URLSessionDataTask不支持后台下载。

创build一个URLSessionDownloadTask并使用它应该工作的委托方法。

按照这个链接