How to get download progress in AFNetworking 2.0? How to get download progress in AFNetworking 2.0? ios ios

How to get download progress in AFNetworking 2.0?


You should observe the fractionCompleted property of your NSProgress object using KVO:

NSURL *url = [NSURL URLWithString:@"http://www.hfrmovies.com/TheHobbitDesolationOfSmaug48fps.mp4"];NSURLRequest *request = [NSURLRequest requestWithURL:url];AFHTTPSessionManager *session = [AFHTTPSessionManager manager];NSProgress *progress;NSURLSessionDownloadTask *downloadTask = [session downloadTaskWithRequest:request progress:&progress destination:^NSURL *(NSURL *targetPath, NSURLResponse *response) {    // …} completionHandler:^(NSURLResponse *response, NSURL *filePath, NSError *error) {    [progress removeObserver:self forKeyPath:@"fractionCompleted" context:NULL];    // …}];[downloadTask resume];[progress addObserver:self            forKeyPath:@"fractionCompleted"               options:NSKeyValueObservingOptionNew               context:NULL];

Then add the observer method:

- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context{    if ([keyPath isEqualToString:@"fractionCompleted"]) {        NSProgress *progress = (NSProgress *)object;        NSLog(@"Progress… %f", progress.fractionCompleted);    } else {        [super observeValueForKeyPath:keyPath ofObject:object change:change context:context];    }}

Of course, you should check keyPath and/or object parameters to decide if that's the object/property you want to observe.

You can also use the setDownloadTaskDidWriteDataBlock: method from AFURLSessionManager (from which AFHTTPSessionManager inherits) to set a block for receiving download progress updates.

[session setDownloadTaskDidWriteDataBlock:^(NSURLSession *session, NSURLSessionDownloadTask *downloadTask, int64_t bytesWritten, int64_t totalBytesWritten, int64_t totalBytesExpectedToWrite) {    NSLog(@"Progress… %lld", totalBytesWritten);}];

This AFNetworking method maps the URLSession:downloadTask:didWriteData:totalBytesWritten:totalBytesExpectedToWrite: method from NSURLSessionDownloadDelegate protocol to a more convenient block mechanism.

BTW, Apple's KVO implementation is severely broken. I recommend using a better implementation like the one proposed by Mike Ash with MAKVONotificationCenter. If you are interested in reading why Apple's KVO is broken, read Key-Value Observing Done Right by Mike Ash.


I faced a similar problem, and found a solution.

Check the link below:http://cocoadocs.org/docsets/AFNetworking/2.0.1/Categories/UIProgressView+AFNetworking.html

#import <AFNetworking/UIKit+AFNetworking.h>

and use the additional method available to your UIProgressView

setProgressWithDownloadProgressOfTask:animated:

How I did it:

NSURLSessionDownloadTask *downloadTask = [manager downloadTaskWithRequest:request  progress:nil destination:^NSURL *(NSURL *targetPath, NSURLResponse *response){    NSURL *documentsDirectoryPath = [NSURL fileURLWithPath:[NSSearchPathForDirectoriesInDomains(NSDocumentationDirectory, NSUserDomainMask, YES) firstObject]];    return [documentsDirectoryPath URLByAppendingPathComponent:[targetPath lastPathComponent]];} completionHandler:^(NSURLResponse *response, NSURL *filePath, NSError *error){    NSLog(@"File downloaded to: %@", filePath);}];[self.progressView setProgressWithDownloadProgressOfTask:downloadTask animated:YES];[downloadTask resume];


Simple solutions for Swift:

let sessionConfiguration = NSURLSessionConfiguration.defaultSessionConfiguration()let sessionManager = AFURLSessionManager(sessionConfiguration: sessionConfiguration)let request = NSURLRequest(URL: url)let sessionDownloadTask = sessionManager.downloadTaskWithRequest(request, progress: nil, destination: { (url, response) -> NSURL in            return destinationPath.URLByAppendingPathComponent(fileName) //this is destinationPath for downloaded file            }, completionHandler: { response, url, error in                //do sth when it finishes        })

Now you have 2 options:

  1. Using UIProgressView and setProgressWithDownloadProgressOfTask:

    progressView.setProgressWithDownloadProgressOfTask(sessionDownloadTask, animated: true)
  2. Using AFURLSessionManager and setDownloadTaskDidWriteDataBlock:

    sessionManager.setDownloadTaskDidWriteDataBlock { session, sessionDownloadTask, bytesWritten, totalBytesWritten, totalBytesExpectedToWrite in    let progress = Float(totalBytesWritten)/Float(totalBytesExpectedToWrite)        //do sth with current progress}

At the end do not forget about:

sessionDownloadTask.resume()