Progress downloads for the entire Alamofire session

Alamofire is used to download multiple large files for a single request. I can make progress for each file separately using

Alamofire.request(.GET, imageURL).progress 

But I would like to track the progress of all open sessions right away and don’t know how to do it. (let's say I have 15 files uploaded at the same time) I read a lot of tutorials that deal with the progress of one file, but not for entire sessions.

Can I track progress in this way with Alamofire, and if so, how?

+5
source share
1 answer

In iOS9, you can create your own NSProgress object and observe, for example, fractionCompleted . Then you can addChild :

 private var observerContext = 0 class ViewController: UIViewController { private var progress: NSProgress! override func viewDidLoad() { super.viewDidLoad() progress = NSProgress() progress.addObserver(self, forKeyPath: "fractionCompleted", options: .New, context: &observerContext) downloadFiles() } deinit { progress?.removeObserver(self, forKeyPath: "fractionCompleted") } private func downloadFiles() { let filenames = ["as17-134-20380.jpg", "as17-140-21497.jpg", "as17-148-22727.jpg"] let baseURL = NSURL(string: "http://example.com/path")! progress.totalUnitCount = Int64(filenames.count) progress.completedUnitCount = 0 for filename in filenames { let url = baseURL.URLByAppendingPathComponent(filename) let childProgress = Alamofire.request(.GET, url.absoluteString) .response() { request, response, data, error in // process response } .progress progress.addChild(childProgress, withPendingUnitCount: 1) } } override func observeValueForKeyPath(keyPath: String?, ofObject object: AnyObject?, change: [String : AnyObject]?, context: UnsafeMutablePointer<Void>) { if context == &observerContext { if keyPath == "fractionCompleted" { let percent = change![NSKeyValueChangeNewKey] as! Double print("\(percent)") } } else { super.observeValueForKeyPath(keyPath, ofObject: object, change: change, context: context) } } } 

If you need iOS 7/8 support, you can call becomeCurrentWithPendingUnitCount and resignCurrent :

 for filename in filenames { let url = baseURL.URLByAppendingPathComponent(filename) progress.becomeCurrentWithPendingUnitCount(1) Alamofire.request(.GET, url.absoluteString) .response() { request, response, data, error in // process response } progress.resignCurrent() } 

If you use AFNetworking, this is the same process (i.e. the same methods viewDidLoad , observeValueForKeyPath and deinit as above), but instead of retrieving the Alamofire progress property, use the AFHTTPSessionManager downloadProgressForTask method instead to get the NSProgress associated with NSURLSessionTask . For instance:

 private func getFiles() { let filenames = ["as17-134-20380.jpg", "as17-140-21497.jpg", "as17-148-22727.jpg"] let manager = AFHTTPSessionManager() manager.responseSerializer = AFHTTPResponseSerializer() let baseURL = NSURL(string: "http://example.com/path")! progress.totalUnitCount = Int64(filenames.count) progress.completedUnitCount = 0 for filename in filenames { let url = baseURL.URLByAppendingPathComponent(filename) let task = manager.GET(url.absoluteString, parameters: nil, progress: nil, success: { task, responseObject in // do something with responseObject print(url.lastPathComponent! + " succeeded") }, failure: { task, error in // do something with error print(error) }) if let downloadTask = task, let childProgress = manager.downloadProgressForTask(downloadTask) { progress.addChild(childProgress, withPendingUnitCount: 1) } } } 

Or if you use download tasks:

 private func downloadFiles() { let filenames = ["as17-134-20380.jpg", "as17-140-21497.jpg", "as17-148-22727.jpg"] let manager = AFHTTPSessionManager() let baseURL = NSURL(string: "http://example.com/path")! progress.totalUnitCount = Int64(filenames.count) progress.completedUnitCount = 0 let documents = try! NSFileManager.defaultManager().URLForDirectory(.DocumentDirectory, inDomain: .UserDomainMask, appropriateForURL: nil, create: false) for filename in filenames { let url = baseURL.URLByAppendingPathComponent(filename) let task = manager.downloadTaskWithRequest(NSURLRequest(URL: url), progress: nil, destination: { (temporaryURL, response) -> NSURL in return documents.URLByAppendingPathComponent(url.lastPathComponent!) }, completionHandler: { response, url, error in guard error == nil else { print(error) return } if let name = url?.lastPathComponent { print("\(name) succeeded") } }) if let childProgress = manager.downloadProgressForTask(task) { progress.addChild(childProgress, withPendingUnitCount: 1) } task.resume() } } 
+4
source

Source: https://habr.com/ru/post/1238086/


All Articles