Currently, I've got a problem with the update of the user interface when using a download task. The following function should update the user interface, but it works just sometimes. Why doesn't it work every time I download a file? The log of NSLog
is shown in the debugger every time!
func urlSession(_ session: URLSession, downloadTask: URLSessionDownloadTask, didWriteData bytesWritten: Int64, totalBytesWritten: Int64, totalBytesExpectedToWrite: Int64) {
let curDownloadSize = totalBytesWritten / (1024*1024)
let totalDownloadSize = totalBytesExpectedToWrite / (1024*1024)
if curDownloadSize != oldDownloadSize {
DispatchQueue.main.async {
self.progressLabel!.text = "\(self.curDownloadSize)MB / \(self.totalDownloadSize)MB"
self.progressView!.progress = Float(totalBytesWritten) / Float(totalBytesExpectedToWrite)
NSLog("Download progress: \(Float(totalBytesWritten) / Float(totalBytesExpectedToWrite))");
}
}
}
progressLabel
and progressView
are both available at this time.
BTW, I have tested it with the same file multiple times and sometimes it works, sometimes it doesn't.
Update: I read about using a second dispatch queue like this
DispatchQueue.global(qos: .utility).async {
DispatchQueue.main.async {
(same as above)
}
}
but this is also working just sometimes.
Recently, I solved the problem.
The problem occurs if too many events are pushed to the main queue. It just occurred with a very good internet connection. In this case the callback has been called too often.
My solution:
progressCounter += 1
if progressCounter % 30 == 0 {
DispatchQueue.main.async {
self.progressLabel!.text = "\(self.curDownloadSize)MB / \(self.totalDownloadSize)MB"
self.progressView!.progress = Float(totalBytesWritten) / Float(totalBytesExpectedToWrite)
NSLog("Download progress: \(Float(totalBytesWritten) / Float(totalBytesExpectedToWrite))");
}
}
The progressCounter
has been initialized to 0 before.