Swift - HTTP网络操作库Alamofire使用详解3(文件下载,断点续传)
相关文章系列:(文章代码均已升级至Swift3)
Swift - HTTP网络操作库Alamofire使用详解1(配置,以及数据请求)
Swift - HTTP网络操作库Alamofire使用详解2(文件上传)
[当前文章] Swift - HTTP网络操作库Alamofire使用详解3(文件下载,断点续传)
Swift - HTTP网络操作库Alamofire使用详解4(用户权限认证)
Swift - HTTP网络操作库Alamofire使用详解1(配置,以及数据请求)
Swift - HTTP网络操作库Alamofire使用详解2(文件上传)
[当前文章] Swift - HTTP网络操作库Alamofire使用详解3(文件下载,断点续传)
Swift - HTTP网络操作库Alamofire使用详解4(用户权限认证)
七,使用Alamofire进行文件下载
下面代码将logo图片下载下来保存到用户文档目录下(Documnets目录),文件名不变。
//指定下载路径(文件名不变) let destination: DownloadRequest.DownloadFileDestination = { _, response in let documentsURL = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask)[0] let fileURL = documentsURL.appendingPathComponent(response.suggestedFilename!) //两个参数表示如果有同名文件则会覆盖,如果路径中文件夹不存在则会自动创建 return (fileURL, [.removePreviousFile, .createIntermediateDirectories]) } //开始下载 Alamofire.download("http://www.hangge.com/blog/images/logo.png", to: destination) .response { response in print(response) if let imagePath = response.destinationURL?.path { let image = UIImage(contentsOfFile: imagePath) } } }将logo图片下载下来保存到用户文档目录下的file1子目录(Documnets/file1目录),文件名改成myLogo.png。
//指定下载路径和保存文件名 let destination: DownloadRequest.DownloadFileDestination = { _, _ in let documentsURL = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask)[0] let fileURL = documentsURL.appendingPathComponent("file1/myLogo.png") //两个参数表示如果有同名文件则会覆盖,如果路径中文件夹不存在则会自动创建 return (fileURL, [.removePreviousFile, .createIntermediateDirectories]) } //开始下载 Alamofire.download("http://www.hangge.com/blog/images/logo.png", to: destination) .response { response in print(response) if let imagePath = response.destinationURL?.path { let image = UIImage(contentsOfFile: imagePath) } } }
2,使用默认提供的下载路径
Alamofire内置的许多常用的下载路径方便我们使用,简化代码。注意的是,使用这种方式如果下载路径下有同名文件,不会覆盖原来的文件。
比如,下载到用户文档目录下可以改成:
let destination = DownloadRequest.suggestedDownloadDestination(for: .documentDirectory) Alamofire.download("http://www.hangge.com/blog/images/logo.png", to: destination)
3,下载时附带请求参数
如果下载文件时需要传递一些参数,我们可以将参数拼接在 url 后面。也可以配置在 download 方法里的 parameters 参数中(其实这个方式最终也是拼接到 url 后面)。
4,下载进度
(1)下面代码在文件下载过程中会不断地打印下载进度,同时下载完成后也会打印完成信息。
5,断点续传(Resume Data)
hangge_972.zip(2015-12-06)
//下面这两种方式效果是一样的 Alamofire.download("http://www.hangge.com/blog/images/logo.png?foo=bar", to: destination) Alamofire.download("http://www.hangge.com/blog/images/logo.png", parameters: ["foo": "bar"], to: destination)
4,下载进度
(1)下面代码在文件下载过程中会不断地打印下载进度,同时下载完成后也会打印完成信息。
Alamofire.download("http://www.hangge.com/favicon.ico", to: destination) .downloadProgress { progress in print("当前进度: \(progress.fractionCompleted)") } .responseData { response in if let data = response.result.value { print("下载完毕!") let image = UIImage(data: data) } }(2)下载的过程中我们也可以得到已下载部分的大小,以及文件总大小。(单位都是字节)
Alamofire.download("http://www.hangge.com/favicon.ico", to: destination) .downloadProgress { progress in print("已下载:\(progress.completedUnitCount/1024)KB") print("总大小:\(progress.totalUnitCount/1024)KB") } .responseData { response in if let data = response.result.value { print("下载完毕!") let image = UIImage(data: data) } }
5,断点续传(Resume Data)
当下载过程中被意外停止时,可以在响应方法中把已下载的部分保存起来,下次再从断点继续下载。
下面通过样例演示如何断点续传:
(1)程序启动后自动开始下载文件
(2)点击“停止下载”,终止下载并把已下载的数据保存起来,进度条停止走动。
(3)点击“继续下载”,从上次终止的地方继续下载,进度条继续走动。
import UIKit import Alamofire class ViewController: UIViewController { //停止下载按钮 @IBOutlet weak var stopBtn: UIButton! //继续下载按钮 @IBOutlet weak var continueBtn: UIButton! //下载进度条 @IBOutlet weak var progress: UIProgressView! //下载文件的保存路径( var destination:DownloadRequest.DownloadFileDestination! //用于停止下载时,保存已下载的部分 var cancelledData: Data? //下载请求对象 var downloadRequest: DownloadRequest! override func viewDidLoad() { super.viewDidLoad() //设置下载路径。保存到用户文档目录,文件名不变,如果有同名文件则会覆盖 self.destination = { _, response in let documentsURL = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask)[0] let fileURL = documentsURL.appendingPathComponent(response.suggestedFilename!) //两个参数表示如果有同名文件则会覆盖,如果路径中文件夹不存在则会自动创建 return (fileURL, [.removePreviousFile, .createIntermediateDirectories]) } //页面加载完毕就自动开始下载 self.downloadRequest = Alamofire.download( "http://dldir1.qq.com/qqfile/qq/QQ7.9/16621/QQ7.9.exe", to: destination) self.downloadRequest.downloadProgress(queue: DispatchQueue.main, closure: downloadProgress) //下载进度 self.downloadRequest.responseData(completionHandler: downloadResponse) //下载停止响应 } //下载过程中改变进度条 func downloadProgress(progress: Progress) { //进度条更新 self.progress.setProgress(Float(progress.fractionCompleted), animated:true) print("当前进度:\(progress.fractionCompleted*100)%") } //下载停止响应(不管成功或者失败) func downloadResponse(response: DownloadResponse<Data>) { switch response.result { case .success(let data): //self.image = UIImage(data: data) print("文件下载完毕: \(response)") case .failure: self.cancelledData = response.resumeData //意外终止的话,把已下载的数据储存起来 } } //停止按钮点击 @IBAction func stopBtnClick(_ sender: AnyObject) { self.downloadRequest?.cancel() self.stopBtn.isEnabled = false self.continueBtn.isEnabled = true } //继续按钮点击 @IBAction func continueBtnClick(_ sender: AnyObject) { if let cancelledData = self.cancelledData { self.downloadRequest = Alamofire.download(resumingWith: cancelledData, to: destination) self.downloadRequest.downloadProgress(queue: DispatchQueue.main, closure: downloadProgress) //下载进度 self.downloadRequest.responseData(completionHandler: downloadResponse) //下载停止响应 self.stopBtn.isEnabled = true self.continueBtn.isEnabled = false } } override func didReceiveMemoryWarning() { super.didReceiveMemoryWarning() } }源码下载:
hangge_972.zip(2015-12-06)
hangge_972.zip(2016-09-23 Swift3最新版)
我想请教两个问题
1.多次停止下载,再重新开始,resumedata并不能定位到原来的位置,好像是ios11出现的问题,这个怎么解决呢?
2.如果退出程序,怎么获取resumeData? applicationWillTerminate这个方法是不能得到返回的resumedata
我也是这么写的,但是不知道为啥参数传不到后台~~~
你好,Alamofire带参数下载文件要怎么写呢?
貌似要用到这个方法:
Alamofire.download(<#T##url: URLConvertible##URLConvertible#>, method: <#T##HTTPMethod#>, parameters: <#T##Parameters?#>, encoding: <#T##ParameterEncoding#>, headers: <#T##HTTPHeaders?#>, to: <#T##DownloadRequest.DownloadFileDestination?##DownloadRequest.DownloadFileDestination?##(URL, HTTPURLResponse) -> (destinationURL: URL, options: DownloadRequest.DownloadOptions)#>),请问这个方法要怎么用啊?
谢谢分享
你好,我这有个问题描述下:我要下载的是一个pdf文件,后台给的下载url路径因为里面有中文,所以我用url.addingPercentEncoding(withAllowedCharacters: .urlQueryAllowed)!给转换了,下载完成以后获取文件路径打开以后文档的名字也变成了被转码的符号名(就这样的:%E5%E6%A1%A3--2017.08.09),然后我用webview加载的时候NSURL.fileURL(withPath: path!)就会报错,请问这种情况整体来说怎么处理比较好呢?
这个太奇怪了,使用这个下载的文件,如果遍历下载目录的是可以看到的,但是 fileManager.fileExists(atPath: filePath)为false
下载的文件并没有保存起来,是需要自己去保存吗?
你好 能不能写个 退出app 回来再下载还是 这样的断点续传呢
你好,我断点下载一直成功不了:
//下载停止响应(不管成功或者失败)
func downloadResponse(response: DownloadResponse<Data>) {
switch response.result {
case .success(let data):
//self.image = UIImage(data: data)
print("文件下载完毕: \(response)")
case .failure:
self.cancelledData = response.resumeData //意外终止的话,把已下载的数据储存起来
}
}
就是response.resumeData一直为nil,不知道为什么。。
站长怎么获取下载文件的大小呢?
站长你好!怎样读取已经下载好的数据呢!以本demo为例!
hangge你的源码里没有Alamofire.xcodeproj 源码运行不了 而且按照你Alamofire使用详解1中引入alamofire的方法 还是提示没有Alamofire 并且现在从git上下载alamofire后选择alamofire.framework的时候有三个版本了 需要选择ios的版本 希望你补充一片引入alamofire的文章 多谢了
我想请问下 在样例1中,如何手动保存路径和文件名。因为刚接触到swift,公司要求做这个项目 有点急。比如我想把我的路径设置成 比如我想保存在他默认路径的子目录下的文件名(zheng)中,请问如何设置,谢谢了哈。情况有点急 麻烦您了哈。
站长你好。请问通过【self.downloadRequest = Alamofire.download(.GET "http://www.baidu.com/favicon.ico", destination: destination)】下载,能否手动更改所下载的图片的文件名?谢谢!
希望给博客添加RSS订阅
给力,加油站长!向你学习.