接下來,我們嘗試加入progress bar,讓這個專案更完整一點。
如果要progress bar有作用,我們需要用到URLSession delegation的一些methods。
ps. 這篇原文來自Apple的Fetching data into memory
好,我們開始吧!
我們一樣用Part 1的程式碼,只是稍做修改。在Viewcontroller上面加入UIProgressView並且設定IBOutlet。
然後加入兩個property:
UI部份都設定好後,開始後面邏輯的處理。
在原來的startLoad方法,把URLSession用closure的方式給予初始化設定,並設定delegate給自己。
在這邊我們會用到3個屬於URLSessionDataDelegate的方法:
個人習慣用extension把delegate和原本的class區隔開來,覺得這樣比較簡潔不會都混在一塊。
接下來我們就試著在simulator上build並看看結果!儘量找一些檔案大一點的圖片,比較能看出效果:
如果要progress bar有作用,我們需要用到URLSession delegation的一些methods。
ps. 這篇原文來自Apple的Fetching data into memory
好,我們開始吧!
我們一樣用Part 1的程式碼,只是稍做修改。在Viewcontroller上面加入UIProgressView並且設定IBOutlet。
然後加入兩個property:
//作為接收data的容器
var receivedData:Data?
//檔案大小
var expectedContentLength = 0
UI部份都設定好後,開始後面邏輯的處理。
在原來的startLoad方法,把URLSession用closure的方式給予初始化設定,並設定delegate給自己。
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
//Session with configuration | |
private lazy var session: URLSession = { | |
let config = URLSessionConfiguration.default | |
config.waitsForConnectivity = true | |
return URLSession(configuration: config, delegate: self, delegateQueue: nil) | |
}() |
url
在這個方法裡面我們會驗證status code是否正確來判斷有沒有錯誤產生,並且取得檔案的大小.Session(_: data Task: did Receive: completion Handler:) url
將收到的data丟到receivedData並且更新progress bar進度.Session(_: data Task: did Receive:) url
將收到的完整data轉換成UIImage並呈現在ImageViewSession(_: task: did Complete With Error:)
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
//MARK: - URLSessionDataDelegate | |
extension ViewController: URLSessionDataDelegate { | |
func urlSession(_ session: URLSession, dataTask: URLSessionDataTask, didReceive response: URLResponse, completionHandler: @escaping (URLSession.ResponseDisposition) -> Void) { | |
guard let httpResponse = response as? HTTPURLResponse, (200...299).contains(httpResponse.statusCode) else { | |
completionHandler(.cancel) | |
return | |
} | |
//get full lenth of your content | |
expectedContentLength = Int(response.expectedContentLength) | |
completionHandler(.allow) | |
} | |
func urlSession(_ session: URLSession, dataTask: URLSessionDataTask, didReceive data: Data) { | |
self.receivedData?.append(data) | |
//count percent and update progress | |
if let receivedCount = self.receivedData{ | |
let percentageDownload = Float(receivedCount.count / self.expectedContentLength) | |
DispatchQueue.main.async { | |
self.progressView1.progress = percentageDownload | |
} | |
} | |
} | |
func urlSession(_ session: URLSession, task: URLSessionTask, didCompleteWithError error: Error?){ | |
DispatchQueue.main.async { | |
self.button1.isEnabled = true | |
self.progressView1.progress = 1.0 | |
if let error = error { | |
self.handleClientError(error) | |
} | |
//when completed receive data, put data to imageview | |
if let receivedData = self.receivedData { | |
self.imageview1.image = UIImage(data: receivedData) | |
} | |
} | |
} | |
} |
個人習慣用extension把delegate和原本的class區隔開來,覺得這樣比較簡潔不會都混在一塊。
接下來我們就試著在simulator上build並看看結果!儘量找一些檔案大一點的圖片,比較能看出效果:
留言
張貼留言