上文中大家已經(jīng)了解了
NSURLSession的使用和機(jī)制,本文著重講解Alamofire的后臺(tái)下載機(jī)制和開發(fā)中可能會(huì)遇到的坑
根據(jù)Alamofire的鏈?zhǔn)巾憫?yīng),我們暫且敲出如下代碼:
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("下載進(jìn)度:\(progress)")
}.response { (downloadResponse) in
print("下載回掉:\(downloadResponse)")
}
當(dāng)我們進(jìn)入后臺(tái)

下載出現(xiàn)中斷,直到我們回到前臺(tái),才能繼續(xù)下載
來到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("下載進(jìn)度:\(progress)")
}.response { (downloadResponse) in
print("下載回掉:\(downloadResponse)")
}
run起來,你想到了啥,-999哈哈。。。

需要保持manager在整個(gè)控制器的生命周期,so
var manager = SessionManager()
run,額,進(jìn)入后臺(tái)中斷的問題還是有問題,so,
AppDelegate下載權(quán)限
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("下載回調(diào): \(downloadResponse)")
}
.downloadProgress { (progress) in
print("下載進(jìn)度 : \(progress)")
}
來到AppDelegate.swift
//用于保存后臺(tái)下載的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已經(jīng)處理了,將依賴下沉
SessionDelegate 類中實(shí)現(xiàn)了NSURLSessionDelegate協(xié)議的urlSessionDidFinishEvents這個(gè)后臺(tái)下載任務(wù)完成后回調(diào)的代理方法
open func urlSessionDidFinishEvents(forBackgroundURLSession session: URLSession) {
sessionDidFinishEventsForBackgroundURLSession?(session)
}
并在SessionManager的初始化中進(jìn)行了實(shí)現(xiàn)

總結(jié)
Alamofire是對(duì)URLSession進(jìn)行封裝,所以這兩種方式進(jìn)行后臺(tái)下載,原理是一樣的。只是 Alamofire 使用更加簡(jiǎn)潔方便,依賴下沉,網(wǎng)絡(luò)層下沉。