[Xcode 實際操做]8、網絡與多線程-(16)使用網址會話對象URLSession下載圖片並顯示下載進度

目錄:[Swift]Xcode實際操做html

本文將演示如何經過網址會話對象URLSession顯示下載圖片的進度。swift

網址會話對象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, width: 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, width: 0, height: 36)
 25         //設置進度條的前景視圖的背景顏色爲綠色
 26         foregroundView.backgroundColor = UIColor.green
 27         
 28         //設置標籤對象的位置在(20,160),尺寸爲(280,36),
 29         progressLabel.frame = CGRect(x: 20, y: 160, width: 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 }
相關文章
相關標籤/搜索