本文将演示如何通过网址会话对象URLSession显示下载图片的进度。
网址会话对象URLSession具有在后台上传和下载、暂停和恢复网络操作、丰富的代理模式等优点。
在项目导航区,打开视图控制器的代码文件【ViewController.swift】
1 import UIKit 2 3 //首先给当前的视图控制器类,添加一个下载代理协议,用来实时检测下载进度 4 class ViewController: UIViewController, URLSessionDownloadDelegate { 5 6 //创建两个视图,作为实时下载的进度条 7 var backgroundView:UIView = UIView() 8 var foregroundView:UIView = UIView() 9 //创建一个标签对象,显示下载进度的百分比 10 var progressLabel:UILabel = UILabel() 11 12 override func viewDidLoad() { 13 super.viewDidLoad() 14 // Do any additional setup after loading the view, typically from a nib. 15 16 //对进度条视图的进行样式设置 17 //设置进度条的背景视图位于(16,106),尺寸为(288,44) 18 backgroundView.frame = CGRect(x: 16, y: 106, 288, height: 44) 19 //设置进度条的背景视图的背景颜色为浅灰色 20 backgroundView.backgroundColor = UIColor.lightGray 21 22 //设置进度条的前景视图位于(20,110),尺寸为(0,36), 23 //它的初始宽度为0 ,当图片下载时,根据下载的进度,调整图片的宽度 24 foregroundView.frame = CGRect(x: 20, y: 110, 0, height: 36) 25 //设置进度条的前景视图的背景颜色为绿色 26 foregroundView.backgroundColor = UIColor.green 27 28 //设置标签对象的位置在(20,160),尺寸为(280,36), 29 progressLabel.frame = CGRect(x: 20, y: 160, 280, height: 36) 30 //设置标签对象的文字对齐方式设置为居中对齐 31 progressLabel.textAlignment = NSTextAlignment.center 32 33 //将背景视图添加到当前视图控制器的根视图 34 self.view.addSubview(backgroundView) 35 //将前景视图添加到当前视图控制器的根视图 36 self.view.addSubview(foregroundView) 37 //将标签对象添加到当前视图控制器的根视图 38 self.view.addSubview(progressLabel) 39 40 //创建一个网址对象,指定请求网络图片的地址 41 let url = URL(string: "https://www.cnblogs.com/strengthen/images/logo.png") 42 //创建一个网络请求对象 43 let request:URLRequest = URLRequest(url: url!) 44 45 //网址会话URLSession在2013年发布,苹果对它的定位是作为旧的网络请求接口的替代者。 46 //这里获得网址会话的单例对象,生成单例对象的方法buildSession()在下文实现 47 let urlSession = self.buildSession() as Foundation.URLSession 48 //创建一个执行下载操作的网络请求任务 49 let task = urlSession.downloadTask(with: request) 50 //任务创建后,调用resume方法开始工作 51 task.resume() 52 } 53 54 //添加一个方法,用来生成网址会话对象 55 func buildSession() -> Foundation.URLSession 56 { 57 //创建一个网址会话对象 58 var session:URLSession? = nil 59 60 //获得网址会话配置的单例对象 61 let config = URLSessionConfiguration.default 62 63 //通过网址会话配置对象,创建一个网址会话对象, 64 //并设置对象的代理为当前视图控制器对象 65 session = URLSession(configuration: config, delegate: self, delegateQueue: nil) 66 //返回设置好的网址会话对象 67 return session! 68 } 69 70 //添加一个代理方法,用来响应下载任务完成后的的动作 71 func urlSession(_ session: URLSession, downloadTask: URLSessionDownloadTask,didFinishDownloadingTo location: URL) 72 { 73 //创建一个异常捕捉语句,用来执行图片下载后的移动操作 74 do 75 { 76 //获得网络下载后,位于缓存目录的,图片原始存储路径 77 let originalPath = location.path 78 //并在控制台打印输出原始存储路径 79 print("Original location:(originalPath)") 80 81 //创建一个字符串,作为图片存储的目标位置 82 let targetPath:String = NSHomeDirectory() + "/Documents/logo.png" 83 84 //获得文件管理对象,它的主要功能包括: 85 //1.读取文件中的数据 86 //2.向文件中写入数据 87 //3.删除或复制文件 88 //4.移动文件 89 //5.比较两个文件的内容 90 //6.测试文件的存在性 91 let fileManager:FileManager = FileManager.default 92 //判断目标位置的文件是否已经存在,如果不存在,则进行移动操作 93 if !fileManager.fileExists(atPath: targetPath) 94 { 95 //将下载后的图片,从原始位置,移动到目标位置 96 try fileManager.moveItem(atPath: originalPath, toPath: targetPath) 97 //在控制台打印输出图片存储后的位置 98 print("new location:(targetPath)") 99 } 100 } 101 catch 102 { 103 print("Network error.") 104 } 105 } 106 107 //创建一个代理方法,用来响应下载任务的进度变化 108 func urlSession(_ session: URLSession, downloadTask: URLSessionDownloadTask,didWriteData bytesWritten: Int64, totalBytesWritten: Int64, totalBytesExpectedToWrite: Int64) 109 { 110 //计算已经从网络下载的数据量, 111 //与总共需要下载的数据量的比值。 112 let rate:CGFloat = CGFloat(totalBytesWritten)/CGFloat(totalBytesExpectedToWrite) 113 114 //从一个分离的线程,切换至主线程,以进行界面的改动 115 DispatchQueue.main.async(execute: { () in 116 //利用各个得到的比值,更新进度条前景视图的宽度 117 self.foregroundView.frame.size.width = rate * 280 118 //如果数据全部下载完成, 119 if rate == 1.0 120 { 121 //设置标签对象的文字内容,提示用户下载成功 122 self.progressLabel.text = "Finished !!!" 123 } 124 }) 125 } 126 127 //添加一个代理方法,响应任务恢复的事件, 128 func urlSession(_ session: URLSession, downloadTask: URLSessionDownloadTask,didResumeAtOffset fileOffset: Int64, expectedTotalBytes: Int64) 129 { 130 print(fileOffset) 131 } 132 133 override func didReceiveMemoryWarning() { 134 super.didReceiveMemoryWarning() 135 // Dispose of any resources that can be recreated. 136 } 137 }