Alamofire(二)URLSessiongithub
Alamofire(三)后台下载原理swift
@TOCapi
URLSession实现后台下载的步骤以下图:markdown
background
的模式的 configuration
。configuration有 三种模式 ,只有background 的模式才能进行后台下载。 而后,经过configuration初始化网络下载会话 session
,设置相关代理,回调数据信号响应。 最后,session建立downloadTask
任务-resume
启动 (默认状态:suspend),具体代码以下:// 1:初始化一个background的模式的configuration let configuration = URLSessionConfiguration.background(withIdentifier: self.createID()) // 2:经过configuration初始化网络下载会话 let session = URLSession.init(configuration: configuration, delegate: self, delegateQueue: OperationQueue.main) // 3:session建立downloadTask任务-resume启动 let url = URL(string: "https://dldir1.qq.com/qqfile/QQforMac/QQ_V6.5.5.dmg")! session.downloadTask(with: url).resume() 复制代码
//MARK: - session代理 extension ViewController:URLSessionDownloadDelegate{ //下载完成回调 func urlSession(_ session: URLSession, downloadTask: URLSessionDownloadTask, didFinishDownloadingTo location: URL) { // 下载完成 - 开始沙盒迁移 print("下载完成 - \(location)") let locationPath = location.path //拷贝到用户目录(文件名以时间戳命名) let documnets = NSHomeDirectory() + "/Documents/" + self.lgCurrentDataTurnString() + ".mp4" print("移动地址:\(documnets)") //建立文件管理器 let fileManager = FileManager.default try! fileManager.moveItem(atPath: locationPath, toPath: documnets) } //下载进度回调 func urlSession(_ session: URLSession, downloadTask: URLSessionDownloadTask, didWriteData bytesWritten: Int64, totalBytesWritten: Int64, totalBytesExpectedToWrite: Int64) { print(" bytesWritten \(bytesWritten)\n totalBytesWritten \(totalBytesWritten)\n totalBytesExpectedToWrite \(totalBytesExpectedToWrite)") print("下载进度: \(Double(totalBytesWritten)/Double(totalBytesExpectedToWrite))\n") } } 复制代码
class AppDelegate: UIResponder, UIApplicationDelegate { var window: UIWindow? //用于保存后台下载的completionHandler var backgroundSessionCompletionHandler: (() -> Void)? func application(_ application: UIApplication, handleEventsForBackgroundURLSession identifier: String, completionHandler: @escaping () -> Void) { self.backgroundSessionCompletionHandler = completionHandler } } 复制代码
注意:咱们经过handleEventsForBackgroundURLSession保存相应的回调,这也是很是必要的!告诉系统后台下载回来及时刷新屏幕网络
func urlSessionDidFinishEvents(forBackgroundURLSession session: URLSession) { print("后台任务下载回来") //由于涉及到UI刷新,须要确保在主线程中进行 //若是不执行下面代码,会致使刚进入前台时页面卡顿,影响用户体验,同时还会打印警告信息。 DispatchQueue.main.async { guard let appDelegate = UIApplication.shared.delegate as? AppDelegate, let backgroundHandle = appDelegate.backgroundSessionCompletionHandler else { return } backgroundHandle() } } 复制代码
注意:若是不实现第6步这个代理里面的回调函数的执行,系统会打印警告信息:`Warning: Application delegate received call to - application:handleEventsForBackgroundURLSession:completionHandler: but the completion handler was never called. 虽然这样仍是能够实现后台下载,可是会致使总在IOS系统总在后台刷新,致使性能浪费,出现页面卡顿,影响用户体验。session
handleEventsForBackgroundURLSession
方法的completionHandler
回调,这是很是重要的。告诉系统后台下载回来及时刷新屏幕.在讲解Alamofire后台下载前,有必要先熟悉一下Alamofire下载须要使用的几个关键类。app
参考:大神Cooci博客:juejin.cn/post/684490…框架