Alamofire-后臺(tái)下載

SessionManager

SessionManager 作為管理類,只做配置相關(guān)的設(shè)置,定義上傳、下載等功能的入口函數(shù),具體功能的實(shí)現(xiàn),數(shù)據(jù)的處理則下沉到其他相關(guān)類處理,使用非常簡(jiǎn)潔,方便,容易理解

初始化

  public static let `default`: SessionManager = {
        let configuration = URLSessionConfiguration.default
        configuration.httpAdditionalHeaders = SessionManager.defaultHTTPHeaders
        return SessionManager(configuration: configuration)
    }()

public init(
        configuration: URLSessionConfiguration = URLSessionConfiguration.default,
        delegate: SessionDelegate = SessionDelegate(),
        serverTrustPolicyManager: ServerTrustPolicyManager? = nil)
    {
        self.delegate = delegate
        self.session = URLSession(configuration: configuration, delegate: delegate, delegateQueue: nil)
        commonInit(serverTrustPolicyManager: serverTrustPolicyManager)
    }
  • 自定義URLSessionConfigurationhttpAdditionalHeaders信息,有助于后臺(tái)阻止非法請(qǐng)求
  • URLSession的代理移交給SessionDelegate,達(dá)到任務(wù)分離的目的

后臺(tái)下載
后臺(tái)下載需要我們定義一個(gè)用于后臺(tái)下載的sessionManager,這里我們包裝成一個(gè)單例

struct BackgroundManager {
    static let shared = BackgroundManager()
    let manager: SessionManager = {
        let config = URLSessionConfiguration.background(withIdentifier: "com.alamofire.background")
        config.httpAdditionalHeaders = SessionManager.defaultHTTPHeaders
        config.sharedContainerIdentifier = "group.com.alamofire"
        return SessionManager(configuration: config)
    }()
}

下載代碼:

        BackgroundManager.shared.manager.download(url) { (url, res) -> (destinationURL: URL, options: DownloadRequest.DownloadOptions) in
            let documentUrl = FileManager.default.urls(for: .documentationDirectory, in: .userDomainMask).first
            let fileUrl = documentUrl?.appendingPathComponent(res.suggestedFilename!)
            return (fileUrl!, [.removePreviousFile, .createIntermediateDirectories])
            }
            .downloadProgress { (progress) in
                print("------\(progress)")
            }
            .response { (response) in
                print("完成")
        }

從下面的SessionManager.init方法可以看到,sessionDelegate實(shí)現(xiàn)了閉包sessionDidFinishEventsForBackgroundURLSession

private func commonInit(serverTrustPolicyManager: ServerTrustPolicyManager?) {
        session.serverTrustPolicyManager = serverTrustPolicyManager
        delegate.sessionManager = self
        delegate.sessionDidFinishEventsForBackgroundURLSession = { [weak self] session in
            guard let strongSelf = self else { return }
            DispatchQueue.main.async { strongSelf.backgroundCompletionHandler?() }
        }
    }
//sessionDelegate 后臺(tái)下載完成代理方法
open func urlSessionDidFinishEvents(forBackgroundURLSession session: URLSession) {
        sessionDidFinishEventsForBackgroundURLSession?(session)
    }

delegate.sessionDidFinishEventsForBackgroundURLSession會(huì)在session后臺(tái)下載完成后執(zhí)行,故而我們只要strongSelf.backgroundCompletionHandler保存AppDelegate授權(quán)后臺(tái)執(zhí)行的閉包completionHandler就可以了,即

 func application(_ application: UIApplication, handleEventsForBackgroundURLSession identifier: String, completionHandler: @escaping () -> Void) {
        BackgroundManager.shared.manager.backgroundCompletionHandler = completionHandler
    }

如此,當(dāng)后臺(tái)下載完成后,最終會(huì)回調(diào)執(zhí)行系統(tǒng)的閉包completionHandler
如果最后不執(zhí)行系統(tǒng)的completionHandler,會(huì)有以下影響:

  • 造成界面刷新卡頓
  • 打印臺(tái)會(huì)輸出警告

Warning: Application delegate received call to -
application:handleEventsForBackgroundURLSession:completionHandler:
but the completion handler was never called.

執(zhí)行結(jié)果:
當(dāng)下載過(guò)程中,進(jìn)入后臺(tái),則會(huì)停止進(jìn)度打印


進(jìn)入后臺(tái)

當(dāng)過(guò)一會(huì)回到前臺(tái)時(shí),直接輸出完成,說(shuō)明在后臺(tái)是在下載的


回到前臺(tái)
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容