【问题标题】:AFNetworking : upload image with other parametersAFNetworking : 上传带有其他参数的图片
【发布时间】:2013-12-05 07:13:47
【问题描述】:

首先,感谢您阅读这个问题。

我正在开发使用 JSON 网络服务的应用程序。在应用程序中,我需要使用带有一些参数的图像(配置文件图像)调用 web 服务。 我的 JSON 请求应与以下相同...

{
  "adduser": {
  "firstname": "testFirstName",
  "lastname": "testLastName",
  "email": "test@test.com",
  "projectids" : "1"
  }
  }

还有其他变量profileimage 用于上传图片。

我已经写了以下代码。

    NSDictionary *dictParameter = @{@"adduser": @{@"firstname": firstName, @"lastname":lastName,@"email":email, @"projectids":@"1"}};
    AFHTTPRequestOperationManager *manager = [AFHTTPRequestOperationManager manager];
    AFHTTPRequestOperation *op = [manager POST:strURL parameters:dictParameter constructingBodyWithBlock:^(id<AFMultipartFormData> formData) {
        } success:^(AFHTTPRequestOperation *operation, id responseObject) {
                NSLog(@"Success: %@ ***** %@", operation.responseString, responseObject);
            } failure:^(AFHTTPRequestOperation *operation, NSError *error) {
                NSLog(@"Error: %@ ***** %@", operation.responseString, error);
            }];
 [op start];

以上代码记录以下错误。

Error: <br />
<b>Notice</b>:  Undefined index: json in <b>/opt/lampp/htdocs/testproject/app/webroot/webservices/include.php</b> on line <b>15</b><br />
{"status":"failure","message":"Your Request is Empty"} ***** Error Domain=NSCocoaErrorDomain Code=3840 "The operation couldn’t be completed. (Cocoa error 3840.)" (JSON text did not start with array or object and option to allow fragments not set.) UserInfo=0x8abe490 {NSDebugDescription=JSON text did not start with array or object and option to allow fragments not set.}

如果我使用以下代码,它就可以正常工作。但我无法上传图片。

AFHTTPRequestOperationManager *manager = [AFHTTPRequestOperationManager manager];
   [manager POST:strURL parameters:dictParameter success:^(AFHTTPRequestOperation *operation, id responseObject) {

    } failure:^(AFHTTPRequestOperation *operation, NSError *error) {

    }];

谢谢

【问题讨论】:

  • 它不会被优化,因为它会调用你的服务器2次,但临时的解决办法是用你当前的代码返回用户头像的url地址,然后使用UIImageView+AFNetworking下载图片
  • 认为 AFN 对参数做了什么?您的服务器期望什么? AFN在接收层次参数结构时究竟是如何组成部分的?

标签: ios json afnetworking-2


【解决方案1】:

您缺少实际添加要发送到服务器的图像数据的部分。

NSDictionary *dictParameter = @{@"adduser": @{@"firstname": firstName, @"lastname":lastName,@"email":email, @"projectids":@"1"}};

AFHTTPRequestOperationManager *manager = [AFHTTPRequestOperationManager manager];
AFHTTPRequestOperation *op = [manager POST:strURL parameters:dictParameter constructingBodyWithBlock:^(id<AFMultipartFormData> formData) {
[formData appendPartWithFileURL:filePath name:@"image" error:nil];
        } 
success:^(AFHTTPRequestOperation *operation, id responseObject) {
                NSLog(@"Success: %@ ***** %@", operation.responseString, responseObject);
            } 
failure:^(AFHTTPRequestOperation *operation, NSError *error) {
                NSLog(@"Error: %@ ***** %@", operation.responseString, error);
            }];

 [op start];

查看关于 posting a multi-part request 的 AFNetworking 文档。

【讨论】:

  • 这是正确的,也是 OPs 代码中的一个问题。但这并不能解释错误。我怀疑,参数有问题。通常,发送分层结构化参数(如 JSON)不是“标准”。因此,无论 AFN 对它们做什么,都需要服务器端的自定义代码。
  • 我尝试添加 [formData appendPartWithFileData:imageData name:@"profileimage" fileName:@"photo.jpg" mimeType:@"image/jpeg"];它仍然给出同样的错误
  • @CouchDeveloper:可能你是对的,但它与其他代码一起工作的原因是什么(有问题描述)
  • @Playcool 在可行的情况下,AFN 使用 不同的 HTTP 消息,其 Content-Type 为 application/x-www-form-urlencoded。显然,对于这种内容类型,参数将被编码,以便服务器可以正确解码。您的原始 HTTP 请求使用 multipart/form-data MIME 类型作为 Content-Type,这需要参数的不同表示。也许,我需要在答案中添加一个详细解释
  • @CouchDeveloper 感谢您的解释。我告诉我的网络服务开发人员更改请求参数。让我检查一下,它会工作还是不工作。谢谢
【解决方案2】:

使用 ASIFormDataRequest 库查看以下代码。

-(IBAction)postPhotoButtonClickedButtonClicked:(id)sender
{
    [textViewStatusBox resignFirstResponder];
    NSLog(@"postPhotoButtonClicked");
    UIImagePickerController * picker = [[UIImagePickerController alloc] init];
    picker.delegate = self;
    picker.sourceType = UIImagePickerControllerSourceTypeSavedPhotosAlbum;
    [self presentModalViewController:picker animated:YES];
}
- (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info {
    NSString *randomPictureName = [NSString stringWithFormat:@"%@.png", [self generateRandomString]] ;
    [picker dismissModalViewControllerAnimated:YES];
    UIImage *selectedImage = [info objectForKey:@"UIImagePickerControllerOriginalImage"];
    NSData *imageData = UIImagePNGRepresentation(selectedImage);
    ASIFormDataRequest *request = [ASIFormDataRequest requestWithURL:[NSURL URLWithString:@"http://webber.im/iphone/post_library.php"]];
    [request setPostValue:@"ASv48umPgx0tyuu9PnjxcQ" forKey:@"key"];
    [request addData:imageData withFileName:randomPictureName andContentType:@"multipart/form-data" forKey:@"picture"];
    [request setDelegate:self];
    [request startSynchronous];
    NSError *error = [request error];
    if (!error) {
        NSString *response = [request responseString];
     }
    }

这里我有两个参数keypicture。您可以使用自己的参数对其进行修改。 希望对你有很大帮助。

干杯

【讨论】:

    【解决方案3】:

    最后,我发现 JSON+formdata (image) 不适用于 AFNetworking。 所以,我把一项任务分成两份, 1) 使用AFNetworkingformData appendPartWithFileURL函数上传图片 2) 上传图片成功后,从服务器响应中获取图片名称。使用该图像名称调用添加用户网络服务。

    它现在正在工作。

    【讨论】:

      【解决方案4】:

      NSMutableDictionary *dicData = [[NSMutableDictionary alloc] initWithCapacity:1];

      [dicData setObject:placeName forKey:@"name"];
      
      [dicData setObject:[NSNumber numberWithFloat:latitude] forKey:@"latitude"];
      
      [dicData setObject:[NSNumber numberWithFloat:longitude] forKey:@"longitude"];
      
      [dicData setObject: [NSNumber numberWithLong:categoryId] forKey:@"categoryId"];
      
      [dicData setObject:@"1" forKey:@"userId"];
      
      number=arc4random();
      NSLog(@"Random Number=%d",number);
      
      str=[NSString stringWithFormat:@"%d",number];
      
      AFHTTPRequestOperation *op = [manager POST:insertPlaceData parameters:dicData constructingBodyWithBlock:^(id<AFMultipartFormData> formData) {
      
          //do not put image inside parameters dictionary as I did, but append it!
      
          [formData appendPartWithFileData:imgData name:@"image" fileName:[str stringByAppendingString:@".jpg"] mimeType:@"image/jpeg"];
      
          } success:^(AFHTTPRequestOperation *operation, id responseObject) {
           //   NSLog(@"JSON: %@", [responseObject description]);
      
              MainScreen *mainScreen=[[MainScreen alloc]init];
              [self.navigationController pushViewController:mainScreen animated:YES];
      
          } failure:^(AFHTTPRequestOperation *operation, NSError *error) {
            //  NSLog(@"Error: %@", [error description]);
              UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:@"Error Retrieving data"
                                                                  message:[error localizedDescription]
                                                                 delegate:nil
                                                        cancelButtonTitle:@"Ok"
                                                        otherButtonTitles:nil];
              [alertView show];
      
          }];
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2019-08-24
        • 2023-03-22
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多