關於 URLSession - part2

接下來,我們嘗試加入progress bar,讓這個專案更完整一點。
如果要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給自己。
//Session with configuration
private lazy var session: URLSession = {
let config = URLSessionConfiguration.default
config.waitsForConnectivity = true
return URLSession(configuration: config, delegate: self, delegateQueue: nil)
}()
在這邊我們會用到3個屬於URLSessionDataDelegate的方法:
//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並看看結果!儘量找一些檔案大一點的圖片,比較能看出效果:


留言