在后台不调用请求块的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:后台传输注意事项”中概述,主要是:
-
使用基于委托的
URLSession
和后台URLSessionConfiguration
。 -
只使用上传和下载任务,没有完成处理程序。
-
在应用程序委托中实现
application(_:handleEventsForBackgroundURLSession:completionHandler:)
,保存完成处理程序并开始后台会话。在你的
URLSessionDelegate
实现urlSessionDidFinishEvents(forBackgroundURLSession:)
,调用保存的完成处理程序让OS知道你已经完成了处理后台请求的完成。
所以,一起拉:
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
并使用它应该工作的委托方法。
按照这个链接
- 如何在Swift中列出符合协议的所有类?
- firebase,swift,ios – 无法获取默认标记Error Domain = com.firebase.iid Code = 6“(null)”
- 检查字典数组是否已经有一个元素
- 为什么在我打开localNotification中的string数组时返回nil?
- 即使“plist”中的“UIBackgroundModes”中存在“voip”,iOS设备在iOS10中重启设备后也不会自动启动
- 多个button连接button的最佳做法
- 用Xcode 7运行UITesting时出现'NSInternalInconsistencyException'
- 在iOS系统中,可以通过Bluetooth PAN进行通信
- objc_sync_enter / objc_sync_exit不适用于DISPATCH_QUEUE_PRIORITY_LOW