Domain=NSURLErrorDomain Code=-1021 “request body s

2019-05-14 05:01发布

问题:

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];


                                        }
                                    }

                                }];

回答1:

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.



回答2:

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);
    }];