ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

Alamofire初探(后台下载)

2019-09-24 17:39:47  阅读:304  来源: 互联网

标签:completionHandler print session let 初探 后台 Alamofire 下载


Alamofire后台下载

后台下载

从iOS7以来,苹果推出了NSURLSession后,可以实现后台下载任务

先来看看苹果原生后台下载

  • 设置后台下载请求
let urlString:String = "http://dldir1.qq.com/qqfile/QQforMac/QQ_V6.5.5.dmg"
let config = URLSessionConfiguration.background(withIdentifier: createID())
let session = URLSession.init(configuration: config, delegate: self, delegateQueue: OperationQueue.main)
let downloadTask: URLSessionDownloadTask = session.downloadTask(with: URL(string: urlString)!)
downloadTask .resume()
  • AppDelegate代理方法(当应用处于后台,且后台下载任务完成时回调)
//用于保存后台下载的completionHandler
    var backgroundSessionCompletionHandler: (() -> Void)?
    func application(_ application: UIApplication, handleEventsForBackgroundURLSession identifier: String, completionHandler: @escaping () -> Void) {
        
        print("handleEventsForBackgroundURLSession - \(identifier)")
        self.backgroundSessionCompletionHandler = completionHandler
    }
  • URLSessionDownloadDelegate代理方法
func urlSession(_ session: URLSession, downloadTask: URLSessionDownloadTask, didFinishDownloadingTo location: URL) {
        print("下载完成 - \(location)")
        let locationPath = location.path
        //拷贝到用户目录(文件名以时间戳命名)
        let documnets = NSHomeDirectory() + "/Documents/" + lgCurrentDataTurnString() + ".dmg"
        //创建文件管理器
        let fileManager = FileManager.default
        
        try! fileManager.moveItem(atPath: locationPath, toPath: documnets)
    }
    
    func urlSession(_ session: URLSession, downloadTask: URLSessionDownloadTask, didWriteData bytesWritten: Int64, totalBytesWritten: Int64, totalBytesExpectedToWrite: Int64) {
        print(" bytesWritten \(bytesWritten)\n totalBytesWritten \(totalBytesWritten)\n totalBytesExpectedToWrite \(totalBytesExpectedToWrite)")
        print("下载进度: \(Double(totalBytesWritten)/Double(totalBytesExpectedToWrite))\n")
    }
    func urlSessionDidFinishEvents(forBackgroundURLSession session: URLSession) {
        print("后台任务下载回来,当前线程-\(Thread.current)")

        DispatchQueue.main.async {
        
            guard let appDelegate = UIApplication.shared.delegate as? AppDelegate else {
                return
            }
            guard let backHandler = appDelegate.backgroundSessionCompletionHandler else {
                return
            }
            backHandler()
        }
    }
  • 注意: App Transport Security Settings -> Allow Arbitrary Loads -> YES
  • 注意:urlSession(_ session: URLSession, downloadTask: URLSessionDownloadTask, didFinishDownloadingTo location: URL)方法中,location只是一个磁盘上该文件的临时 URL,只是一个临时文件,需要自己使用FileManager将文件写到应用的目录下(一般来说这种可以重复获得的内容应该放到cache目录下),因为当你从这个委托方法返回时,该文件将从临时存储中删除
  • 注意:最好将handleEventsForBackgroundURLSession中completionHandler保存,在该方法中待下载数据和UI刷新做完后,再调用completionHandler()
  • Swift try?,try! as!,as? 的使用
    • try? 告诉系统可能有错, 也可能没错, 如果发生错误, 那么返回nil, 如果没有发生错误, 会将数据包装成一个可选类型的值返回给我们
    • try! 告诉系统一定没错, 如果发生错误, 程序会崩溃. 不推荐使用
    • as! 向下转型(Downcasting)时使用,由于是强制类型转换,如果转换失败会报runtime运行错误
    • as?和as!操作符的转换规则是一样的,只是as?在转换失败之后会返回nil对象,转换成功之后返回一个可选类型(optional),需要我们拆包使用。由于as?转换失败也不会报错,所以对于能够100%确定使用as!能够转换成功的,使用as!,否则使用as?

Alamofire后台下载

  • 创建一个单例,初始化请求,便于回调
struct LGBackgroundManger {
    static let shared = LGBackgroundManger()
    let manager: SessionManager = {
        let configuration = URLSessionConfiguration.background(withIdentifier: "com.lgcooci.AlamofireTest.demo")
        configuration.httpAdditionalHeaders = SessionManager.defaultHTTPHeaders
        return SessionManager(configuration: configuration)
    }()
}
  • Alamofire下载
LGBackgroundManger.shared.manager
            .download(urlString, method: .get, parameters: nil) {
                (url, response) -> (destinationURL: URL, options: DownloadRequest.DownloadOptions) in
                let documentUrl = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).first
                let fileUrl = documentUrl?.appendingPathComponent(response.suggestedFilename ?? "123.dmg")
                return (fileUrl!, [.createIntermediateDirectories,.removePreviousFile])
            }.response { (downloadResponse) in
                print("下载回调信息:\(downloadResponse)")
            }.downloadProgress { (progress) in
                print("下载进度:\(progress)")
        }
  • AppDelegate代理回调
func application(_ application: UIApplication, handleEventsForBackgroundURLSession identifier: String, completionHandler: @escaping () -> Void) {
        
        print("handleEventsForBackgroundURLSession - \(identifier)")
        LGBackgroundManger.shared.manager.backgroundCompletionHandler = completionHandler
    }
  • 注意: Manager needs to be retained during the session else we get HTTP Error Code -999 .
    After defining manager as global it was retained. Could have defined it as Stored property as well for the class.

标签:completionHandler,print,session,let,初探,后台,Alamofire,下载
来源: https://blog.csdn.net/GuanZeJun123/article/details/101296696

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有