I am getting the NSURLErrorDomain Code=-1021 "request body stream exhausted"
NSLocalizedDescription=request body stream exhausted, NSUnderlyingError=0x2088c080 "request body stream exhausted"}
This error is generated when uploading multiple big size images
I am using AFNetworking and tried to search for a fix online, but didn't succeed
NSDictionary *clientUniqueId = [NSDictionary dictionaryWithObject:NSLocalizedString(uniqueDrId, nil) forKey:@"clientUniqueId"];
NSMutableURLRequest *request = [client multipartFormRequestWithMethod:@"POST"
path:pendingUpload.urlPath
parameters:clientUniqueId
constructingBodyWithBlock:^(id<AFMultipartFormData> formData)
{
[formData appendPartWithFormData:[pendingUpload dataRecordData] name:@"dr"];
NSArray *attachments = pendingUpload.attachments;
if (attachments != nil) {
for (Attachment *attachment in attachments) {
[formData appendPartWithFileData:attachment.data
name:attachment.key
fileName:attachment.filename
mimeType:attachment.contentType];
}
}
}];
As described in the AFNetworking FAQ:
Why are some upload requests failing with the error "request body stream exhausted"? What does that mean, and how do I fix this?
When uploading over a 3G or EDGE connection, requests may fail with "request body stream exhausted". Using -throttleBandwidthWithPacketSize:delay:
your multipart form construction block, you can set a maximum packet size and delay according to the recommended values (kAFUploadStream3GSuggestedPacketSize
and kAFUploadStream3GSuggestedDelay
). This lowers the risk of the input stream exceeding its allocated bandwidth. Unfortunately, as of iOS 6, there is no definite way to distinguish between a 3G, EDGE, or LTE connection. As such, it is not recommended that you throttle bandwidth based solely on network reachability. Instead, you should consider checking for the "request body stream exhausted" in a failure block, and then retrying the request with throttled bandwidth.
I was experiencing this issue also and didn't have any luck with the throttleBandwithWithPacketSize
method. I believe in my case it was an authentication challenge issue.
What I finally did was switch to the URLSession connection method in AFNetworking 2.0 and that seemed to solve it for me. Here is the code I ended up using:
NSString *uploadAttachmentURL = @"https://mydomain.zendesk.com/api/v2/uploads.json?filename=screenshot.jpeg";
NSData *imageData = UIImageJPEGRepresentation(image, 1.0);
NSURLSessionConfiguration *configuration = [NSURLSessionConfiguration defaultSessionConfiguration];
_afHTTPSessionManager = [[AFHTTPSessionManager alloc] initWithSessionConfiguration:configuration];
// hack to allow 'text/plain' content-type to work
NSMutableSet *contentTypes = [NSMutableSet setWithSet:_AFOpManager.responseSerializer.acceptableContentTypes];
[contentTypes addObject:@"text/plain"];
_afHTTPSessionManager.responseSerializer.acceptableContentTypes = contentTypes;
[_afHTTPSessionManager.requestSerializer setAuthorizationHeaderFieldWithUsername:@"[USERNAME]" password:@"[PASSWORD]"];
[_afHTTPSessionManager POST:uploadAttachmentURL parameters:nil constructingBodyWithBlock:^(id<AFMultipartFormData> formData) {
[formData appendPartWithFileData:imageData name:@"screenshot" fileName:@"photo.jpg" mimeType:@"image/jpeg"];
} success:^(NSURLSessionDataTask *task, id responseObject) {
DDLogError(@"screenshot operation success! %@", responseObject);
} failure:^(NSURLSessionDataTask *task, NSError *error) {
DDLogError(@"Operation Error: %@", error);
}];