zoukankan      html  css  js  c++  java
  • [Xcode 实际操作]八、网络与多线程-(16)使用网址会话对象URLSession下载图片并显示下载进度

    目录:[Swift]Xcode实际操作

    本文将演示如何通过网址会话对象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 }
  • 相关阅读:
    成为高级Java工程师,你必须要看的技术书籍
    MYSQL存储引擎介绍--应用场景
    RocketMq的安装使用
    调用第三方物流公司API即时查询物流信息
    移动终端处理器构成和基带芯片概述
    数据库水平切分(拆库拆表)的实现原理
    使用TortoiseGit操作分支的创建与合并
    mysql安装教程
    初步认识dubbo--小案例
    【算法】混合流体模拟demo
  • 原文地址:https://www.cnblogs.com/strengthen/p/10062166.html
Copyright © 2011-2022 走看看