Alamofire之SessionManager后台下载

上文中大家已经了解了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)")
            }

当我们进入后台


Alamofire之SessionManager后台下载_第1张图片

下载出现中断,直到我们回到前台,才能继续下载

来到GitHub,在Alamofire的Issues中,来搜索我们想要的答案
Alamofire之SessionManager后台下载_第2张图片
Alamofire之SessionManager后台下载_第3张图片
Alamofire之SessionManager后台下载_第4张图片

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哈哈。。。

Alamofire之SessionManager后台下载_第5张图片

需要保持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之SessionManager后台下载_第6张图片
总结

Alamofire是对URLSession进行封装,所以这两种方式进行后台下载,原理是一样的。只是 Alamofire 使用更加简洁方便,依赖下沉,网络层下沉。

你可能感兴趣的:(Alamofire之SessionManager后台下载)