Find the Download Progress of a file in swift
Solution 1
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
Solution 2
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()
Solution 3
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)")
loopidio
Updated on July 23, 2022Comments
-
loopidio almost 2 years
I have searched but haven't found a relevant answer only in Objective C. Is there a way to find the progress of the download of a file in Swift, so that to show it to user? I am new to iOS programming and I have tried with NSURLSession but without success.
EDIT: I have used this method as seen in this post, but I can't seem to understand how to get the progress status:
func downloadFile(page: NSString){ finished = false var statusCode:Int = 0 println("Download starting") let url = NSURL(string: page) let task = NSURLSession.sharedSession().dataTaskWithURL(url!) {(data, response, error) in if error != nil { println("download failed with error \(error?.localizedDescription)") } else { println("Expected Content-Length \(response.expectedContentLength)") self.contentLength = response.expectedContentLength if let httpResponse = response as? NSHTTPURLResponse { println("Status Code of number \(self.countDownload) is \(httpResponse.statusCode)") statusCode = httpResponse.statusCode } } } task.resume() }
Thank you in advance
-
dar512 about 9 yearsI believe this only works if you use the delegate methods and not a closure.
-
Jeffrey about 9 years@dar512 That's true. I should note I don't believe there is any way to find the progress if you're using a closure.