I am using AFURLSessionManager to create a new download task:
AFURLSessionManager* manager = ... NSProgress* p = nil; NSURLSessionDownloadTask* downloadTask = [manager downloadTaskWithRequest:request progress:&p destination:^NSURL*(NSURL* targetPath, NSURLResponse* response) {...} completionHandler:^(NSURLResponse* response, NSURL* filePath, NSError* error) {...} ]; [downloadTask resume];
The file gets downloaded fine, however, how do I get progress notifications?
p
is always set to nil. I've filed an issue for that.
I've also tried to call setDownloadTaskDidWriteDataBlock
on the manager, and I do get progress notifications there but I receive them all grouped together after the file has been downloaded.
Seems like this area is still a bit buggy in AFNetworking 2.0
Any ideas?
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With