【问题标题】:How can I send a multipart HTTP request on iOS?如何在 iOS 上发送多部分 HTTP 请求?
【发布时间】:2016-05-14 00:25:50
【问题描述】:

我正在尝试使用多部分方法将照片上传到我的 iOS 应用程序的服务器上。但是,我似乎无法让它工作。我收到错误消息:

您指定的前提条件中至少有一个不成立。 Bucket POST 必须是机柜类型的多部分。我已经查看了这个错误,但似乎无法弄清楚如何最终解决这个问题。该应用的 Android 版本可以运行,所以 API 应该不是问题?

这是我的代码:

  //photo file 
  NSData *data = [[NSFileManager defaultManager] contentsAtPath:filePath];

  NSMutableDictionary* _params = [[NSMutableDictionary alloc] init];
[_params setObject:uploadInfo.key forKey:@"key"];
[_params setObject:uploadInfo.aaki forKey:@"AWSAccessKeyId"];
[_params setObject:uploadInfo.acl forKey:@"acl"];
[_params setObject:uploadInfo.policy forKey:@"policy"];
[_params setObject:uploadInfo.signature forKey:@"signature"];
[_params setObject:uploadInfo.success_action_status forKey:@"success_action_status"];
[_params setObject:@"image/jpeg" forKey:@"Content-Type"];

NSURL* requestURL = [NSURL URLWithString:uploadInfo.path];

NSMutableURLRequest *request = [[NSMutableURLRequest alloc] init];
[request setCachePolicy:NSURLRequestReloadIgnoringLocalCacheData];
[request setHTTPShouldHandleCookies:NO];
[request setTimeoutInterval:30];
[request setHTTPMethod:@"POST"];

NSMutableData *body = [NSMutableData data];
 for (NSString *param in _params) {
 [body appendData:[[NSString stringWithFormat:@"%@", [_params objectForKey:param]] dataUsingEncoding:NSUTF8StringEncoding]];
  }

 if (data) {
   [body appendData:data];
 }

[request setHTTPBody:body];

    [request setURL:requestURL];
NSURLResponse * response = nil;
NSError * error = nil;
NSData * data1 = [NSURLConnection sendSynchronousRequest:request returningResponse:&response error:&error];

NSString *responseString = [[NSString alloc] initWithData:data1 encoding:NSUTF8StringEncoding];
NSLog(@"%@",responseString);

【问题讨论】:

  • 我没有设置任何代表,这有什么不同吗?
  • 您还有其他图片参数,还是只上传不带任何参数的图片?
  • 我还在代码中的 for 循环中附加了参数
  • 总共需要上传多少张图片?
  • 只有一张图片到服务器

标签: ios nsurlrequest multipart


【解决方案1】:

尝试使用另一个简单的代码。

NSDictionary *aParams =@{}; //your param dictionary here

    UIImage *aImage = [UIImage imageNamed:@"your image here"]; //set yout image here
    NSString *aStrParamName = @"image parameter name here";// set parameter name of image here

    NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:@"uploadInfo.path"]];// url here
    [request setHTTPMethod:@"POST"];
    [request setTimeoutInterval:30];
    NSString *uuidStr = [[NSUUID UUID] UUIDString];
    [request addValue:[NSString stringWithFormat:@"multipart/form-data; boundary=%@", uuidStr] forHTTPHeaderField:@"Content-Type"];

    NSURLSessionConfiguration *configuration = [NSURLSessionConfiguration defaultSessionConfiguration];
    NSURLSession *session = [NSURLSession sessionWithConfiguration:configuration];

    NSData *imagedata = UIImageJPEGRepresentation(aImage, (CGFloat)0.6);
    NSData *fileData = UIImagePNGRepresentation([UIImage imageWithData:imagedata]);
    NSData *data = [self createBodyWithBoundary:uuidStr withDictData:aParams data:fileData filename:aStrParamName];

    NSURLSessionUploadTask *task = [session uploadTaskWithRequest:request fromData:data completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) {
        NSAssert(!error, @"%s: uploadTaskWithRequest error: %@", __FUNCTION__, error);

        // parse and interpret the response `NSData` however is appropriate for your app

        NSString *aStr = [[NSString alloc]initWithData:data encoding:NSUTF8StringEncoding];
        NSLog(@"ResponseString:%@",aStr);

        NSMutableDictionary *aMutDict = [NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingMutableContainers error:nil];
        dispatch_async(dispatch_get_main_queue(), ^{

            NSLog(@"responce:%@",aMutDict);

        });
    }];
    [task resume];

还添加下面的方法

- (NSData *)createBodyWithBoundary:(NSString *)boundary withDictData:(NSDictionary *)aDict data:(NSData*)data filename:(NSString *)paramName
{
    NSMutableData *body = [NSMutableData data];

    if (data) {
        //only send these methods when transferring data as well as username and password
        [body appendData:[[NSString stringWithFormat:@"--%@\r\n", boundary] dataUsingEncoding:NSUTF8StringEncoding]];
        [body appendData:[[NSString stringWithFormat:@"Content-Disposition: form-data; name=\"%@\"; filename=\"%@\"\r\n", paramName,@"image.png"] dataUsingEncoding:NSUTF8StringEncoding]];
#warning if you have to chane name of image then change. if there is any error then chane other wise go as it is..
        [body appendData:[[NSString stringWithFormat:@"Content-Type: %@\r\n\r\n", @"image/png"] dataUsingEncoding:NSUTF8StringEncoding]];
        [body appendData:data];
        [body appendData:[@"\r\n" dataUsingEncoding:NSUTF8StringEncoding]];
    }

    for (NSString *aKey in aDict.allKeys) {
        [body appendData:[[NSString stringWithFormat:@"--%@\r\n", boundary] dataUsingEncoding:NSUTF8StringEncoding]];
        [body appendData:[[NSString stringWithFormat:@"Content-Disposition: form-data; name=\"%@\"\r\n\r\n%@\r\n", aKey,aDict[aKey]] dataUsingEncoding:NSUTF8StringEncoding]];

    }
    [body appendData:[[NSString stringWithFormat:@"--%@--\r\n", boundary] dataUsingEncoding:NSUTF8StringEncoding]];

    return body;
}

【讨论】:

    【解决方案2】:

    尝试如下。

    //photo file 
    NSData *data = [[NSFileManager defaultManager] contentsAtPath:filePath];
    NSMutableDictionary* _params = [[NSMutableDictionary alloc] init];
    [_params setObject:uploadInfo.key forKey:@"key"];
    [_params setObject:uploadInfo.aaki forKey:@"AWSAccessKeyId"];
    [_params setObject:uploadInfo.acl forKey:@"acl"];
    [_params setObject:uploadInfo.policy forKey:@"policy"];
    [_params setObject:uploadInfo.signature forKey:@"signature"];
    [_params setObject:uploadInfo.success_action_status forKey:@"success_action_status"];
    
    NSURL* requestURL = [NSURL URLWithString:uploadInfo.path];
    
    NSMutableURLRequest *request = [[NSMutableURLRequest alloc] init];
    [request setCachePolicy:NSURLRequestReloadIgnoringLocalCacheData];
    [request setHTTPShouldHandleCookies:NO];
    [request setTimeoutInterval:30];
    [request setHTTPMethod:@"POST"];
    
    //Create boundary, it can be anything
    NSString *boundary = @"------VohpleBoundary4QuqLuM1cE5lMwCy";
    
    // set Content-Type in HTTP header
    NSString *contentType = [NSString stringWithFormat:@"multipart/form-data; boundary=%@", boundary];
    [request setValue:contentType forHTTPHeaderField: @"Content-Type"];
    
    NSMutableData *body = [NSMutableData data];
    for (NSString *param in _params) {
        [body appendData:[[NSString stringWithFormat:@"--%@\r\n", boundary] dataUsingEncoding:NSUTF8StringEncoding]];
        [body appendData:[[NSString stringWithFormat:@"Content-Disposition: form-data; name=\"%@\"\r\n\r\n", param] dataUsingEncoding:NSUTF8StringEncoding]];
        [body appendData:[[NSString stringWithFormat:@"%@\r\n", [_params objectForKey:param]] dataUsingEncoding:NSUTF8StringEncoding]];
    }
    NSString *FileParamConstant = @"image";   // Key of webservice in which you need to send image
    // add image data
    if (data) {
        [body appendData:[[NSString stringWithFormat:@"--%@\r\n", boundary] dataUsingEncoding:NSUTF8StringEncoding]];
        [body appendData:[[NSString stringWithFormat:@"Content-Disposition: form-data; name=\"%@\"; filename=\"image.jpg\"\r\n", FileParamConstant] dataUsingEncoding:NSUTF8StringEncoding]];
        [body appendData:[@"Content-Type: image/jpeg\r\n\r\n" dataUsingEncoding:NSUTF8StringEncoding]];
        [body appendData:data];
        [body appendData:[[NSString stringWithFormat:@"\r\n"] dataUsingEncoding:NSUTF8StringEncoding]];
    }
    //Close off the request with the boundary
    [body appendData:[[NSString stringWithFormat:@"--%@--\r\n", boundary] dataUsingEncoding:NSUTF8StringEncoding]];
    [request setHTTPBody:body];
    
    // set the content-length
    NSString *postLength = [NSString stringWithFormat:@"%lu", (unsigned long)[body length]];
    [request setValue:postLength forHTTPHeaderField:@"Content-Length"];
    [request setURL:requestURL];
    NSURLResponse * response = nil;
    NSError * error = nil;
    NSData * data1 = [NSURLConnection sendSynchronousRequest:request returningResponse:&response error:&error];
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2014-01-24
      • 2015-12-19
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-09-02
      相关资源
      最近更新 更多