Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

NSProgress fractionCompleted key-value observing method not called

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?

like image 875
MLQ Avatar asked Feb 10 '14 11:02

MLQ


1 Answers

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];
like image 177
Yas Tabasam Avatar answered Sep 19 '22 17:09

Yas Tabasam