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

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,293评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,604评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,958评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,729评论 1 277
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,719评论 5 366
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,630评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,000评论 3 397
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,665评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,909评论 1 299
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,646评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,726评论 1 330
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,400评论 4 321
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,986评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,959评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,197评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 44,996评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,481评论 2 342

推荐阅读更多精彩内容