上文中大家已经了解了
NSURLSession
的使用和机制,本文着重讲解Alamofire的
后台下载机制和开发中可能会遇到的坑
根据Alamofire的链式响应,我们暂且敲出如下代码:
SessionManager.default.download(self.urlDownloadStr) { (url, response) -> (destinationURL: URL, options: DownloadRequest.DownloadOptions) in
let documentUrl = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).first
let fileUrl = documentUrl?.appendingPathComponent(response.suggestedFilename!)
return (fileUrl!,[.removePreviousFile,.createIntermediateDirectories])
}.downloadProgress { (progress) in
print("下载进度:\(progress)")
}.response { (downloadResponse) in
print("下载回掉:\(downloadResponse)")
}
当我们进入后台
下载出现中断,直到我们回到前台,才能继续下载
来到GitHub,在Alamofire的Issues中,来搜索我们想要的答案
so,我们要自定义manager
...
let configuration = URLSessionConfiguration.background(withIdentifier: "com.episode.backgroundDownload")
let manager = SessionManager(configuration: configuration)
紧接着
manager.download(self.urlDownloadStr) { (url, response) -> (destinationURL: URL, options: DownloadRequest.DownloadOptions) in
let documentUrl = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).first
let fileUrl = documentUrl?.appendingPathComponent(response.suggestedFilename!)
return (fileUrl!,[.removePreviousFile,.createIntermediateDirectories])
}.downloadProgress { (progress) in
print("下载进度:\(progress)")
}.response { (downloadResponse) in
print("下载回掉:\(downloadResponse)")
}
run起来,你想到了啥,-999
哈哈。。。
需要保持manager
在整个控制器的生命周期,so
var manager = SessionManager()
run,额,进入后台中断的问题还是有问题,so,
AppDelegate
下载权限
struct EpisodeBackgroundManger {
static let shared = EpisodeBackgroundManger()
let manager: SessionManager = {
let configuration = URLSessionConfiguration.background(withIdentifier: "com.episode.Alamofire.testing")
configuration.httpAdditionalHeaders = SessionManager.defaultHTTPHeaders
configuration.timeoutIntervalForRequest = 10
configuration.timeoutIntervalForResource = 10
return SessionManager(configuration: configuration)
}()
}
EpisodeBackgroundManger.shared.manager
.download(self.urlDownloadStr) { (url, response) -> (destinationURL: URL, options: DownloadRequest.DownloadOptions) in
let documentUrl = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).first
let fileUrl = documentUrl?.appendingPathComponent(response.suggestedFilename!)
return (fileUrl!,[.removePreviousFile,.createIntermediateDirectories])
}
.response { (downloadResponse) in
print("下载回调: \(downloadResponse)")
}
.downloadProgress { (progress) in
print("下载进度 : \(progress)")
}
来到AppDelegate.swift
//用于保存后台下载的completionHandler
var backgroundSessionCompletionHandler: (() -> Void)?
func application(_ application: UIApplication, handleEventsForBackgroundURLSession identifier: String, completionHandler: @escaping () -> Void) {
print("hello - \(identifier)")
EpisodeBackgroundManger.shared.manager.backgroundCompletionHandler = completionHandler
self.backgroundSessionCompletionHandler = completionHandler
}
控制器还需要处理回掉么,NO
,牛逼的Alamofire
已经处理了,将依赖下沉
SessionDelegate
类中实现了NSURLSessionDelegate
协议的urlSessionDidFinishEvents
这个后台下载任务完成后回调的代理方法
open func urlSessionDidFinishEvents(forBackgroundURLSession session: URLSession) {
sessionDidFinishEventsForBackgroundURLSession?(session)
}
并在SessionManager
的初始化中进行了实现
总结
Alamofire
是对URLSession
进行封装,所以这两种方式进行后台下载,原理是一样的。只是 Alamofire
使用更加简洁方便,依赖下沉,网络层下沉。
网友评论