Find the Download Progress of a file in swift
You can simply observe progress
property of the URLSessionDataTask
object. And you don't need to calculate the progress as other answers suggest here. There is a fractionCompleted
property on the Progress
.
Playground example:
import Foundation
import PlaygroundSupport
let page = PlaygroundPage.current
page.needsIndefiniteExecution = true
let url = URL(string: "https://source.unsplash.com/random/4000x4000")!
let task = URLSession.shared.dataTask(with: url) { _, _, _ in
page.finishExecution()
}
// Don't forget to invalidate the observation when you don't need it anymore.
let observation = task.progress.observe(\.fractionCompleted) { progress, _ in
print(progress.fractionCompleted)
}
task.resume()
Assuming you are downloading a file, there is a subclass of NSURLSessionTask
for the just that, called NSURLSessionDownloadTask
. Below is an excerpt from the NSURLSession documentation on a specific function:
Periodically informs the delegate about the download’s progress.
func URLSession(_ session: NSURLSession, downloadTask downloadTask: NSURLSessionDownloadTask, didWriteData bytesWritten: Int64, totalBytesWritten totalBytesWritten: Int64, totalBytesExpectedToWrite totalBytesExpectedToWrite: Int64 )
For example, you could output the progress to the console by doing:
println("\(totalBytesWritten) / \(totalBytesExpectedToWrite)")
The progress status can be calculated in
URLSession(_:downloadTask:didWriteData:totalBytesWritten:totalBytesExpectedToWrite:)
This is a one of three required methods of protocol NSURLSessionDownloadDelegate. In my case the code of the method looks like this:
func URLSession(session: NSURLSession, downloadTask: NSURLSessionDownloadTask, didWriteData bytesWritten: Int64, totalBytesWritten: Int64, totalBytesExpectedToWrite: Int64) {
// println("download task did write data")
let progress = Float(totalBytesWritten) / Float(totalBytesExpectedToWrite)
dispatch_async(dispatch_get_main_queue()) {
self.progressDownloadIndicator.progress = progress
}
}
I've created a small project, which implements three different approaches:
- download synchronously
- download asynchronously
- download with progress
Check it out: http://goo.gl/veRkA7