Swift. Как отследить процесс загрузки downloadTask? (с использованием completionHandler)
При создании downloadTask мне требуется completionHandler для обработки некоторых данных. В документации сказано: "You should pass a nil completion handler only when creating tasks in sessions whose delegates include a urlSession(_:downloadTask:didFinishDownloadingTo:) method." То есть, при использовании completionHandler методы делегата URLSessionDownloadDelegate по отслеживанию процесса загрузки не работают. Есть ли другой способ отследить прогресс?
Ответы (1 шт):
Автор решения: schmidt9
→ Ссылка
Можно еще отследить используя свойство задания progress и KVO начиная с iOS 11 (см оригинальный ответ), progress.fractionCompleted в примере будет изменяться в диапазоне от 0 до 1
import UIKit
class ViewController: UIViewController {
@IBOutlet var imageView: UIImageView!
var image: UIImage?
var progressKVOContext: UnsafeMutableRawPointer?
override func viewDidLoad() {
super.viewDidLoad()
testDownloadTask()
}
override func observeValue(forKeyPath keyPath: String?, of object: Any?, change: [NSKeyValueChangeKey : Any]?, context: UnsafeMutableRawPointer?) {
if context == &self.progressKVOContext, let keyPath = keyPath {
switch keyPath {
case "fractionCompleted":
guard let progress = object as? Progress else {
return
}
DispatchQueue.main.async {
print("completed \(progress.fractionCompleted)")
}
case "isCancelled":
print(keyPath)
default:
break
}
} else {
super.observeValue(forKeyPath: keyPath, of: object, change: change, context: context)
}
}
func testDownloadTask() {
let session = URLSession.shared
let url = URL(string: "https://upload.wikimedia.org/wikipedia/commons/d/d4/Deerfire_high_res.jpg")!
let task = session.downloadTask(with: url) { [weak self] url, response, error in
if let error = error {
print(error)
return
}
print("saved using callback", url)
// You must move this file or open it for reading before your completion handler returns.
// Otherwise, the file is deleted, and the data is lost.
self?.image = UIImage(contentsOfFile: url!.path)
DispatchQueue.main.async {
self?.imageView.image = self?.image
}
}
task.progress.addObserver(self, forKeyPath: "fractionCompleted", options: .new, context: &self.progressKVOContext)
task.resume()
}
}