I’m using AFNetworking to upload files to a web service using a multi-part POST. Everything works fine when using WiFi but when uploading via 3g the upload fails for files larger than 2 megabytes.
I’ve tried two approaches, both fail at the exact number of bytes sent: 1998848. If the file or files are smaller than that then the upload succeeds.
The Amazon S3 SDK has the same issue and they suggest throttling the upload but I couldn’t find a way to do that with AFNetworking or NSUrlConnection.
I also remember that iOS has a limit of 5 megs per 5 minutes when streaming. I am not sure if this applies but with my 3g speed I am uploading about 2 megs in under a minute. Maybe that could be it? Again, couldn’t find any relevant info on this.
Any ideas? Here’s my code:
Multi-part upload:
NSMutableURLRequest *request = [[DIOSSession sharedSession] multipartFormRequestWithMethod:@"POST" path:[NSString stringWithFormat:@"%@/%@", kDiosEndpoint, @"demotix_services_story/upload"] parameters:params constructingBodyWithBlock: ^(id <AFMultipartFormData> formData) {
for (NSString * fkey in files) {
NSDictionary *file = [files objectForKey:fkey];
NSURL *fileUrl = [NSURL fileURLWithPath:[file valueForKey:@"fileUrl"]];
NSString *fileName = [file valueForKey:@"name"];
[formData appendPartWithFileURL:fileUrl name:fileName error:&error];
}
}];
AFHTTPRequestOperation *operation = [[AFHTTPRequestOperation alloc] initWithRequest:request];
[operation setUploadProgressBlock:^(NSInteger bytesWritten, long long totalBytesWritten, long long totalBytesExpectedToWrite) {
[delegate updateUploadProgress:totalBytesWritten from:totalBytesExpectedToWrite];
}];
[operation setCompletionBlockWithSuccess:success failure:failure];
[operation start];
Combine all files into one and try to stream it:
NSURLRequest *nrequest = [[DIOSSession sharedSession] requestWithMethod:@"POST" path:[NSString stringWithFormat:@"%@/%@", kDiosEndpoint, @"demotix_services_story/upload"] parameters:params];
AFHTTPRequestOperation *noperation = [[AFHTTPRequestOperation alloc] initWithRequest:nrequest];
noperation.inputStream = [NSInputStream inputStreamWithFileAtPath:storePath];
noperation.outputStream = [NSOutputStream outputStreamToMemory];
[noperation setUploadProgressBlock:^(NSInteger bytesWritten, long long totalBytesWritten, long long totalBytesExpectedToWrite) {
[delegate updateUploadProgress:totalBytesWritten from:totalBytesExpectedToWrite];
}];
[noperation setCompletionBlockWithSuccess:success failure:failure];
[noperation start];
Thanks,
Andu
ASIHTTPRequest supports bandwidth throttling.
If you are not willing to switch, you could analyze its code to see how it is down and whether you can extend AFNetworking to do the same. Have a look at the methods: