Alamofire-后台下载

1、枚举 HTTPMethod

rawValue
属性值关联

public enum HTTPMethod: String {
    case options = "OPTIONS"
    case get     = "GET"
    case head    = "HEAD"
    case post    = "POST"
    case put     = "PUT"
    case patch   = "PATCH"
    case delete  = "DELETE"
    case trace   = "TRACE"
    case connect = "CONNECT"
}
2、单例 SessionManager.default
    public static let `default`: SessionManager = {
        let configuration = URLSessionConfiguration.default
        configuration.httpAdditionalHeaders = SessionManager.defaultHTTPHeaders

        return SessionManager(configuration: configuration)
    }()
3、SessionManager.defaultHTTPHeaders
    /// Creates default values for the "Accept-Encoding", "Accept-Language" and "User-Agent" headers.
    public static let defaultHTTPHeaders: HTTPHeaders = {
        // Accept-Encoding HTTP Header; see https://tools.ietf.org/html/rfc7230#section-4.2.3
        let acceptEncoding: String = "gzip;q=1.0, compress;q=0.5"

        // Accept-Language HTTP Header; see https://tools.ietf.org/html/rfc7231#section-5.3.5
        let acceptLanguage = Locale.preferredLanguages.prefix(6).enumerated().map { index, languageCode in
            let quality = 1.0 - (Double(index) * 0.1)
            return "\(languageCode);q=\(quality)"
        }.joined(separator: ", ")

        // User-Agent Header; see https://tools.ietf.org/html/rfc7231#section-5.5.3
        // Example: `iOS Example/1.0 (org.alamofire.iOS-Example; build:1; iOS 10.0.0) Alamofire/4.0.0`
        let userAgent: String = {
            if let info = Bundle.main.infoDictionary {
                let executable = info[kCFBundleExecutableKey as String] as? String ?? "Unknown"
                let bundle = info[kCFBundleIdentifierKey as String] as? String ?? "Unknown"
                let appVersion = info["CFBundleShortVersionString"] as? String ?? "Unknown"
                let appBuild = info[kCFBundleVersionKey as String] as? String ?? "Unknown"

                let osNameVersion: String = {
                    let version = ProcessInfo.processInfo.operatingSystemVersion
                    let versionString = "\(version.majorVersion).\(version.minorVersion).\(version.patchVersion)"

                    let osName: String = {
                        #if os(iOS)
                            return "iOS"
                        #elseif os(watchOS)
                            return "watchOS"
                        #elseif os(tvOS)
                            return "tvOS"
                        #elseif os(macOS)
                            return "OS X"
                        #elseif os(Linux)
                            return "Linux"
                        #else
                            return "Unknown"
                        #endif
                    }()

                    return "\(osName) \(versionString)"
                }()

                let alamofireVersion: String = {
                    guard
                        let afInfo = Bundle(for: SessionManager.self).infoDictionary,
                        let build = afInfo["CFBundleShortVersionString"]
                    else { return "Unknown" }

                    return "Alamofire/\(build)"
                }()

                return "\(executable)/\(appVersion) (\(bundle); build:\(appBuild); \(osNameVersion)) \(alamofireVersion)"
            }

            return "Alamofire"
        }()

        return [
            "Accept-Encoding": acceptEncoding,
            "Accept-Language": acceptLanguage,
            "User-Agent": userAgent
        ]
    }()
4、return SessionManager(configuration: configuration)

4.1、public let delegate: SessionDelegate
4.2、self.delegate = delegate
4.3、代理移交

    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)
    }
5、commonInit(serverTrustPolicyManager: serverTrustPolicyManager)

5.1、delegate.sessionManager = self
5.2、weak var sessionManager: SessionManager?
5.3、后台下载事件,闭包

//SessionManager

    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?() }
        }
    }
6、Alamofire

进入后台暂停下载,再次进入继续下载

        SessionManager.default
            .download(self.urlDownloadStr1) { (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)")
        }
7、全局搜索urlSessionDidFinishEvents

7.1、执行步骤5初始化的delegate.sessionDidFinishEventsForBackgroundURLSession闭包
7.2、SessionManager中有open var backgroundCompletionHandler: (() -> Void)?属性闭包

//extension SessionDelegate: URLSessionDelegate

    open func urlSessionDidFinishEvents(forBackgroundURLSession session: URLSession) {
        sessionDidFinishEventsForBackgroundURLSession?(session)
    }
8、解决6的问题
8.1、配置成background。

会遇到Code=-999问题,断了,变量释放了

        let configuration = URLSessionConfiguration.background(withIdentifier: "com.lgcooci.backgroundDownload")
        let manager = SessionManager(configuration: configuration)
        manager
            .download(self.urlDownloadStr1) { (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)")
        }
8.2、临时变量会释放,所以不能使用临时变量,改成全局变量,保存对象

有后台权限问题,解决Appdelegat。-> 回调 Alamofire-系统URLSession中后台下载
但是没有用到Alamofire的闭包回调,所以有了8.3

    var manager = SessionManager()

        let configuration = URLSessionConfiguration.background(withIdentifier: "com.lgcooci.backgroundDownload")
        manager = SessionManager(configuration: configuration)
        manager
            .download(self.urlDownloadStr1) { (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)")
        }
        manager.backgroundCompletionHandler = {
            print("下载完成来了")
        }
8.3、最终版本->单例和AppDelegate
//单例
struct DYZBackgroundManger {
    
    static let shared = DYZBackgroundManger()
    
    let manager: SessionManager = {
        let configuration = URLSessionConfiguration.background(withIdentifier: "com.lgcooci.AlamofireTest.demo")
        configuration.httpAdditionalHeaders = SessionManager.defaultHTTPHeaders
//        configuration.timeoutIntervalForRequest = 10
//        configuration.timeoutIntervalForResource = 10
//        configuration.sharedContainerIdentifier = "group.com.dyz.AlamofireTest"
        
        return SessionManager(configuration: configuration)
    }()
}
        DYZBackgroundManger.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])
            }
            .downloadProgress { (progress) in
                print("下载进度 : \(progress)")
            }
            .response { (downloadResponse) in
                print("下载回调信息: \(downloadResponse)")
        }
//AppDelegate

    var backgroundSessionCompletionHandler: (() -> Void)?
    
    func application(_ application: UIApplication, handleEventsForBackgroundURLSession identifier: String, completionHandler: @escaping () -> Void) {

        DYZBackgroundManger.shared.manager.backgroundCompletionHandler = completionHandler

    }
9、链式

返回自己

10、cURL

终端 输入 curl http://www.baidu.com
html在线解析工具 https://c.runoob.com/front-end/61

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