I'm trying to track the progress of my HTTP request using AFNetworking and NSProgress. Basically, my request is a multi-part form data which contains text parameters, and image data, all in one block.
This is my code for the upload task, and it seems pretty simple and normal to me:
NSMutableURLRequest *request = [[AFHTTPRequestSerializer serializer] multipartFormRequestWithMethod:@"POST" URLString:@"<THE_API_URL>" parameters:nil constructingBodyWithBlock:constructionBlock];
AFURLSessionManager *manager = [[AFURLSessionManager alloc] initWithSessionConfiguration:[NSURLSessionConfiguration defaultSessionConfiguration]];
manager.responseSerializer = [AFHTTPResponseSerializer serializer];
NSProgress *progress = [[NSProgress alloc] initWithParent:nil userInfo:nil];
[progress addObserver:self forKeyPath:@"fractionCompleted" options:NSKeyValueObservingOptionNew context:NULL];
NSURLSessionUploadTask *uploadTask = [manager uploadTaskWithStreamedRequest:request progress:&progress completionHandler:^(NSURLResponse *response, id responseObject, NSError *error) {
if (error) {
// UI reacts to error
} else {
// Do stuff here
}
}];
[uploadTask resume];
Now, what I don't understand is that the callback observer method isn't getting called even though the upload task completes and succeeds. Can someone help me understand why? Here's my code.
- (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);
}
}
UPDATE: I followed AFNetworking's code for the uploadTaskWithStreamedRequest:...
method and found that they are actually replacing my NSProgress
object from inside uploadTaskWithTask:...
. Naturally, if the NSProgress
pointer is made to point at a new instance, that new instance is not registered for observing the fractionCompleted
property. How can I do key-value observing on this new NSProgress
instance without modifying the AFNetworking code directly?
Well all you need to do is move your observer to after upload task has been created and it is going to work like a charm.
NSProgress *progress;
NSURLSessionUploadTask *uploadTask = [manager uploadTaskWithStreamedRequest:request progress:&progress completionHandler:^(NSURLResponse *response, id responseObject, NSError *error) {
if (error) {
// UI reacts to error
} else {
// Do stuff here
}
}];
[uploadTask resume];
[progress addObserver:self forKeyPath:@"fractionCompleted" options:NSKeyValueObservingOptionNew context:NULL];
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