Aaron Brager
Aaron Brager

Reputation: 66244

NSURLConnection (as part of AFNetworking) doesn't call NSURLConnectionDataDelegate delegate

The Issue

I am using AFNetworking, which generates an NSURLConnection object, to upload a photo.

The NSURLConnection is not making any calls to the

- (void)connection:(NSURLConnection __unused *)connection
   didSendBodyData:(NSInteger)bytesWritten
 totalBytesWritten:(NSInteger)totalBytesWritten
totalBytesExpectedToWrite:(NSInteger)totalBytesExpectedToWrite

method. (It's part of the NSURLConnectionDataDelegate protocol, defined in NSURLConnection.h)

The request is an HTTP POST request with a photo attachment (Content-Disposition "form-data", Mime type "image/jpeg"). This should (I think) result in periodic calls to this method as the upload progresses.

I need the method to display a progress bar to the user. However, the method is not getting called.

Note:

AFNetworking Code

I'm pretty sure this is an NSURLConnection issue, not an AFNetworking issue.

But just in case, here is the relevant code from my AFHTTPClient subclass:

NSMutableURLRequest *request = [self multipartFormRequestWithMethod:@"POST" path:path parameters:parameters constructingBodyWithBlock:constructor];
AFHTTPRequestOperation *operation = [self HTTPRequestOperationWithRequest:request success:success failure:failure];

if (constructor) {
    [operation setUploadProgressBlock:^(NSUInteger bytesWritten, long long totalBytesWritten, long long totalBytesExpectedToWrite) {
        NSLog(@"Sent %lld of %lld bytes", totalBytesWritten, totalBytesExpectedToWrite);
    }];
}

[self enqueueHTTPRequestOperation:operation];

My AFHTTPClient subclass does NOT override ANY of the methods I am calling:

constructor is a block with type (void (^)(id<AFMultipartFormData>)) and is not nil (verified by stepping through code).

When I type po operation.uploadProgress in the debugger, I see $0 = 0x1301d9f0 <__NSMallocBlock__: 0x1301d9f0> so I think the block is being set correctly.

The file always uploads successfully, but the code in the upload progress block is not run, so my progress bar never updates.

Questions

Why isn't NSURLConnection calling this method?

What are the circumstances in which NSURLConnection is supposed to? (It doesn't appear to be well-documented.)

And most importantly, how can I display the upload progress to the user?

Upvotes: 3

Views: 1199

Answers (2)

0xced
0xced

Reputation: 26478

The library maybe implements a connection:didSendBodyData:totalBytesWritten:totalBytesExpectedToWrite: method in a category on NSObject. That would be very nasty but that could explain why the method of AFURLConnectionOperation is not called.

In order to check this assumption, you can run class-dump on your compiled binary. Search for didSendBodyData: in the output. If there’s a match in a category, the library is clearly responsible. The library could also be messing with the Objective-C runtime, but that would be harder to detect than just running class-dump.

Upvotes: 1

Aaron Brager
Aaron Brager

Reputation: 66244

A third-party error reporting library was overriding that delegate method on NSURLConnection. Removing the library resolved the issue. (There was no issue with either AFNetworking or NSURLConnection.)

If you can provide troubleshooting steps that would have isolated this issue faster, I will award the bounty to you. (Keep in mind that the third-party library is compiled, so a source code search wouldn't have worked.)

Upvotes: 3

Related Questions