AFNetworking 3.0 Multipart form data for uploading image error

2.2k Views Asked by At

I've been trying to upload an image to my AWS server using multipart form data afnetworking 3.0 but apparently, every image I tried to upload ended up in the failure block. The codes in written in objective-c.

- (NSURLSessionUploadTask *)uploadImageTask:(NSMutableDictionary *)dictionary
{
    NSString *s3BucketUrl = [dictionary objectForKey:@"s3BucketUrl"];

    NSData *imageData = [dictionary objectForKey:@"imageData"];

    NSString *contentType = [dictionary objectForKey:@"contentType"];

    NSString *filename = [dictionary objectForKey:@"filename"];

    NSMutableURLRequest *request = [[AFHTTPRequestSerializer serializer] multipartFormRequestWithMethod:@"POST" URLString:s3BucketUrl parameters:dictionary constructingBodyWithBlock:^(id<AFMultipartFormData> formData) {

       [formData appendPartWithFileData:imageData name:@"file" fileName:filename mimeType:contentType];
    } error:nil];

    AFURLSessionManager *manager = [[AFURLSessionManager alloc] initWithSessionConfiguration:[NSURLSessionConfiguration defaultSessionConfiguration]];

    NSURLSessionUploadTask *uploadTask = [[NSURLSessionUploadTask alloc] init];
    uploadTask = [manager
                  uploadTaskWithStreamedRequest:request
                  progress:^(NSProgress * _Nonnull uploadProgress) {
                      // This is not called back on the main queue.
                      // You are responsible for dispatching to the main queue for UI updates
                      dispatch_async(dispatch_get_main_queue(), ^{
                          //Update the progress view

                      });
                  }
                  completionHandler:^(NSURLResponse * _Nonnull response, id  _Nullable responseObject, NSError * _Nullable error) {
                      if (!error) {

                          if (self.delegate != nil && [self.delegate respondsToSelector:@selector(onUploadImageTask:)])
                          {
                              [self.delegate onUploadImageTask:nil];
                          }

                      } else {

                          if (self.delegate != nil && [self.delegate respondsToSelector:@selector(onUploadImageTask:)])
                          {
                              [self.delegate onUploadImageTask:error];
                          }
                      }
                  }];

    [uploadTask resume];

    return uploadTask;
}

The error I'm getting is

Error Domain=com.alamofire.error.serialization.response Code=-1011 "Request failed: bad request (400)" UserInfo={NSUnderlyingError=0x170248940 {Error Domain=com.alamofire.error.serialization.response Code=-1016 "Request failed: unacceptable content-type: application/xml" UserInfo={com.alamofire.serialization.response.error.response= { URL: https://....s3.amazonaws.com/ } { status code: 400, headers { Connection = close; "Content-Type" = "application/xml"; Date = "Tue, 20 Dec 2016 01:53:47 GMT"; Server = AmazonS3; "Transfer-Encoding" = Identity; "x-amz-id-2" = "....."; "x-amz-request-id" = ....; } },

I tried changing the content-type for the response serializer and still fail.

1

There are 1 best solutions below

0
On BEST ANSWER

Use this method

-(void)callWebserviceToUploadImageWithParams:(NSMutableDictionary *)_params imgParams:(NSMutableDictionary *)_imgParams videoParms:(NSMutableDictionary *)_videoParams action:(NSString *)_action success:(void (^)(id))_success failure:(void (^)(NSError *))_failure

{
    if ([[AFNetworkReachabilityManager sharedManager] isReachable]) {
        //Here BASE_URL is my URL of web service
        NSString *urlString = [BASE_URL stringByAppendingString:_action];
        NSLog(@"URL : %@",urlString);
        NSMutableURLRequest *urlRequest = [[NSMutableURLRequest alloc] init];
        [urlRequest setURL:[NSURL URLWithString:urlString]];
        [urlRequest setHTTPMethod:@"POST"];
        NSString *boundary = @"---------------------------14737809831466499882746641449";
        NSString *contentType = [NSString stringWithFormat:@"multipart/form-data; boundary=%@",boundary];
        [urlRequest addValue:contentType forHTTPHeaderField: @"Content-Type"];
       // [urlRequest setValue:contentType forHTTPHeaderField:@"Content-type: application/json"]
        NSMutableData *body = [NSMutableData data];
        [_params enumerateKeysAndObjectsUsingBlock: ^(NSString *key, NSString *object, BOOL *stop) {
            [body appendData:[[NSString stringWithFormat:@"\r\n--%@\r\n",boundary] dataUsingEncoding:NSUTF8StringEncoding]];
            [body appendData:[[NSString stringWithFormat:@"Content-Disposition: form-data; name=\"%@\"\r\n\r\n",key] dataUsingEncoding:NSUTF8StringEncoding]];
            [body appendData:[[NSString stringWithFormat:@"%@",object] dataUsingEncoding:NSUTF8StringEncoding]];
        }];
        [_imgParams enumerateKeysAndObjectsUsingBlock: ^(NSString *key, NSData *object, BOOL *stop) {
            if ([object isKindOfClass:[NSData class]]) {
                if (object.length > 0) {
                    [body appendData:[[NSString stringWithFormat:@"\r\n--%@\r\n",boundary] dataUsingEncoding:NSUTF8StringEncoding]];
                    NSLog(@"Timestamp:%@",TimeStamp);
                    [body appendData:[[NSString stringWithFormat:@"Content-Disposition: form-data; name=\"%@\"; filename=\"%@.jpg\"\r\n",key,TimeStamp] dataUsingEncoding:NSUTF8StringEncoding]];
                    [body appendData:[[NSString stringWithFormat:@"Content-Type: application/octet-stream\r\n\r\n"] dataUsingEncoding:NSUTF8StringEncoding]];
                    [body appendData:[NSData dataWithData:object]];
                }

            }
        }];
        [_videoParams enumerateKeysAndObjectsUsingBlock: ^(NSString *key, NSData *object, BOOL *stop) {
            if (object.length > 0) {
                [body appendData:[[NSString stringWithFormat:@"\r\n--%@\r\n",boundary] dataUsingEncoding:NSUTF8StringEncoding]];
                NSLog(@"Timestamp:%@",TimeStamp);
                [body appendData:[[NSString stringWithFormat:@"Content-Disposition: form-data; name=\"%@\"; filename=\"%@.mp4\"\r\n",key,TimeStamp] dataUsingEncoding:NSUTF8StringEncoding]];
                [body appendData:[[NSString stringWithFormat:@"Content-Type: application/octet-stream\r\n\r\n"] dataUsingEncoding:NSUTF8StringEncoding]];
                [body appendData:[NSData dataWithData:object]];
            }
        }];
        [body appendData:[[NSString stringWithFormat:@"\r\n--%@--\r\n",boundary] dataUsingEncoding:NSUTF8StringEncoding]];
        [urlRequest setHTTPBody:body];
        AFHTTPSessionManager* manager = [AFHTTPSessionManager manager];
        manager.responseSerializer.acceptableContentTypes = nil;


        NSURLSessionDataTask *dataTask = [manager dataTaskWithRequest:urlRequest completionHandler:^(NSURLResponse *response, id responseObject, NSError *error) {
            if (error) {
                NSLog(@"Error: %@", error);
                if( _failure )
                {
                    _failure( error) ;
                }
            } else {
                if( _success )
                {
                    _success( responseObject ) ;
                }
            }
        }];
        [dataTask resume];
    }
    else
    {
        [Utility showInterNetConnectionMessage];
        NSError *error;
        if( _failure )
        {
            _failure( error) ;
        }
    }
}

If you are not uploading any video or image then give as nil

USE:

#pragma -mark callwebservice for login
  -(void)callWebserviceFor_upload_Sticker {
    // Check whether Company user login or Individual User login.
    [SVProgressHUD setDefaultMaskType:SVProgressHUDMaskTypeClear];

    //user_id, user_token, emoji_weburl(optional), emoji_picture(file)
    NSMutableDictionary *dict_user_data = [Utility getUserPlistData];
    NSMutableDictionary *params = [[NSMutableDictionary alloc]init];
    [params setValue:[dict_user_data valueForKey:@"user_id"] forKey:@"user_id"];
    [params setValue:[dict_user_data valueForKey:@"user_token"] forKey:@"user_token"];
    NSLog(@"%@",params);

    NSMutableDictionary *imgParams = [[NSMutableDictionary alloc]init];
    [imgParams setValue:UIImageJPEGRepresentation(img_to_upload, 0) forKey:@"emoji_picture"];

    void ( ^successed )( id _responseObject ) = ^( id _responseObject )
    {
        NSLog(@"%@",_responseObject);
        //Your logic after success
    } ;
    void ( ^failure )( NSError* _error ) = ^( NSError* _error ) {
        [SVProgressHUD showErrorWithStatus:@"Failed"];
    } ;

[[WebServiceHendler sharedManager]callWebserviceToUploadImageWithParams:params imgParams:imgParams videoParms:nil action:UPDATE_EMOJI success:successed failure:failure];
}