How to Get Download Progress in Afnetworking 2.0

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.

Getting Download progress with AFNetworking 2.0 + NSProgress + Custom ProgressView

Use AFURLConnectionOperation -setDownloadProgressBlock:, updating the progress with the ratio of totalBytesRead over totalBytesExpectedToRead each time the block is called.

To update your UI element, just call the update through the main thread:

dispatch_async(dispatch_get_main_queue(), ^(void){
//Run UI Updates
});

How to get download progress with AFHTTPSessionManager in AFNetworking 3.0

Link in comments was missleading (NSURLSessionDownloadTask). Sorry about that.

Code below should work though.

Assumption: this code is placed in AFHTTPSessionManager subclass with an NSURLSessionDataTask *testTask ivar declared. It should be easy enough modify as needed.

Vital part of code taken from this answer

- (void)test
{
NSURLRequest *request = [NSURLRequest requestWithURL:[NSURL URLWithString:@"http://eoimages.gsfc.nasa.gov/images/imagerecords/78000/78797/nwpassage_tmo_2012199_lrg.jpg"]];

testTask = [self dataTaskWithRequest:request
completionHandler:^(NSURLResponse * __unused response, id responseObject, NSError *error) {

if (error)
{
//...
NSLog(@"error");
}
else
{
//...

UIImage *result = responseObject;

NSLog(@"Success: %@",NSStringFromCGSize(result.size));
}
}];

[self setDataTaskDidReceiveDataBlock:^(NSURLSession *session,
NSURLSessionDataTask *dataTask,
NSData *data)
{
if (dataTask.countOfBytesExpectedToReceive == NSURLSessionTransferSizeUnknown)
return;

if (dataTask != testTask)
return;

NSUInteger code = [(NSHTTPURLResponse *)dataTask.response statusCode];

if (!(code> 199 && code < 400))
return;

long long bytesReceived = [dataTask countOfBytesReceived];
long long bytesTotal = [dataTask countOfBytesExpectedToReceive];

NSLog(@"... %lld/%lld",
bytesReceived,
bytesTotal);
}];

[testTask resume];
}

AFNetworking 2.0 track file upload progress

The interface of AFHTTPSession doesn't provide a method to set a progress block. Instead, you'll have to do the following:

// 1. Create `AFHTTPRequestSerializer` which will create your request.
AFHTTPRequestSerializer *serializer = [AFHTTPRequestSerializer serializer];

// 2. Create an `NSMutableURLRequest`.
NSMutableURLRequest *request =
[serializer multipartFormRequestWithMethod:@"POST" URLString:@"http://www.myurl.com"
parameters:dataToPost
constructingBodyWithBlock:^(id<AFMultipartFormData> formData) {
[formData appendPartWithFileData:imageData
name:@"attachment"
fileName:@"myimage.jpg"
mimeType:@"image/jpeg"];
}];

// 3. Create and use `AFHTTPRequestOperationManager` to create an `AFHTTPRequestOperation` from the `NSMutableURLRequest` that we just created.
AFHTTPRequestOperationManager *manager = [AFHTTPRequestOperationManager manager];
AFHTTPRequestOperation *operation =
[manager HTTPRequestOperationWithRequest:request
success:^(AFHTTPRequestOperation *operation, id responseObject) {
NSLog(@"Success %@", responseObject);
} failure:^(AFHTTPRequestOperation *operation, NSError *error) {
NSLog(@"Failure %@", error.description);
}];

// 4. Set the progress block of the operation.
[operation setUploadProgressBlock:^(NSUInteger __unused bytesWritten,
long long totalBytesWritten,
long long totalBytesExpectedToWrite) {
NSLog(@"Wrote %lld/%lld", totalBytesWritten, totalBytesExpectedToWrite);
}];

// 5. Begin!
[operation start];

In addition, you don't have to read the image via UIImage and then compress it again using JPEG to get an NSData. Just use +[NSData dataWithContentsOfFile:] to read the file directly from your bundle.

How to show ProgressBar With AFNetworking AFHTTPRequestOperationManager

You set the download-progress-block inside the success block, which is a bit too late ;)

Try this:

AFHTTPRequestOperationManager *manager = [AFHTTPRequestOperationManager manager];    
AFHTTPRequestOperation *operation = [manager GET:@"https:urlWithJson" parameters:nil success:^(AFHTTPRequestOperation *operation, id responseObject) {
NSLog(@"Complete");
} failure:^(AFHTTPRequestOperation *operation, NSError *error) {
NSLog(@"Error: %@", error);
}];

[operation setDownloadProgressBlock:^(NSUInteger bytesRead, long long totalBytesRead, long long totalBytesExpectedToRead) {
myProgressView.progress = (float)totalBytesRead / totalBytesExpectedToRead;
}];

AFNetworking Progress method

I would recommend using the following template for loading images with progress:

AFHTTPSessionManager *manager = [AFHTTPSessionManager manager];
manager.responseSerializer = [AFImageResponseSerializer serializer];

manager.requestSerializer.cachePolicy = NSURLRequestReloadIgnoringLocalAndRemoteCacheData;

[manager GET:url.absoluteString parameters:nil progress:^(NSProgress * _Nonnull downloadProgress) {

float progress = downloadProgress.fractionCompleted;

} success:^(NSURLSessionTask *task, id responseObject) {
UIImage *responseImage = responseObject;

} failure:^(NSURLSessionTask *operation, NSError *error) {
NSLog(Failed with error: %@", error);
}];

and this template for downloading videos with progress:

AFHTTPSessionManager *manager = [AFHTTPSessionManager manager];
NSURLRequest *request = [NSURLRequest requestWithURL:url];
NSURLSessionDownloadTask *downloadTask = [manager downloadTaskWithRequest:request progress:^(NSProgress * _Nonnull downloadProgress) {
float progress = downloadProgress.fractionCompleted;

} destination:^NSURL * _Nonnull(NSURL * _Nonnull targetPath, NSURLResponse * _Nonnull response) {

NSURL *documentsDirectoryURL = [[NSFileManager defaultManager] URLForDirectory:NSDocumentDirectory inDomain:NSUserDomainMask appropriateForURL:nil create:NO error:nil];
return [documentsDirectoryURL URLByAppendingPathComponent:[response suggestedFilename]];

} completionHandler:^(NSURLResponse * _Nonnull response, NSURL * _Nullable filePath, NSError * _Nullable error) {

if(error) {
NSLog(Error %@", error);
}
else {
NSString *path = filePath.relativeString;
}
}
}];

[downloadTask resume];

I hope this helps!

How to use Progress parameter in AFNetworking 2.0

Any time an argument is given as ** it means that you're supposed to pass in the pointer to the pointer to an existing object, not a pointer to the actual object as you would normally do.

In this case, you pass in a pointer to a pointer to an NSProgress object and then observe the changes in that object in order to get the updates.

Example:

// Create a progress object and pass it in
NSProgress *progress;
[sessionManager uploadTaskWithRequest:request fromFile:fileURL progress:&progress completionHandler:^(NSURLResponse *response, id responseObject, NSError *error) {
// Completion code
}];

// Observe fractionCompleted using KVO
[progress addObserver:self
forKeyPath:@"fractionCompleted"
options:NSKeyValueObservingOptionNew
context:NULL];

Then it gets reported in:

- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context
{
[super observeValueForKeyPath:keyPath ofObject:object change:change context:context];

if ([keyPath isEqualToString:@"fractionCompleted"] && [object isKindOfClass:[NSProgress class]]) {
NSProgress *progress = (NSProgress *)object;
NSLog(@"Progress is %f", progress.fractionCompleted);
}
}

How to set download status of UIProgressView in UILabel using AFNetworking?

For more detail see https://stackoverflow.com/a/19380812/5235106

Here is the answer

- (IBAction)ActionPerform:(UIButton *)sender
{
NSURLSessionConfiguration *configuration = [NSURLSessionConfiguration defaultSessionConfiguration];
AFURLSessionManager *manager = [[AFURLSessionManager alloc] initWithSessionConfiguration:configuration];
NSURL *strURL = [NSURL URLWithString:URL];
NSURLRequest *request = [NSURLRequest requestWithURL:strURL];
NSProgress *progress;
NSURLSessionDownloadTask *downloadTask = [manager downloadTaskWithRequest:request progress:&progress destination:^NSURL *(NSURL *targetPath, NSURLResponse *response)
{
NSURL *documentsDirectoryURL = [[NSFileManager defaultManager] URLForDirectory:NSDocumentDirectory inDomain:NSUserDomainMask appropriateForURL:nil create:NO error:nil];
return [documentsDirectoryURL URLByAppendingPathComponent:[response suggestedFilename]];
} completionHandler:^(NSURLResponse *response, NSURL *filePath, NSError *error)
{
NSLog(@"File downloaded to: %@", filePath);
}];
[self.ProgressView setProgressWithDownloadProgressOfTask:downloadTask animated:YES];
[downloadTask resume];
[progress addObserver:self
forKeyPath:@"fractionCompleted"
options:NSKeyValueObservingOptionNew
context:NULL];
}
- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context
{
if ([keyPath isEqualToString:@"fractionCompleted"]) {
NSProgress *progress = (NSProgress *)object;
// update the label text use progress
} else {
[super observeValueForKeyPath:keyPath ofObject:object change:change context:context];
}
}
@end


Related Topics



Leave a reply



Submit