使用 AFNetworking 3.0 上传图像 [关闭]

Posted

技术标签:

【中文标题】使用 AFNetworking 3.0 上传图像 [关闭]【英文标题】:Image Uploading with AFNetworking 3.0 [closed] 【发布时间】:2016-08-31 09:15:09 【问题描述】:

我正在尝试使用 AFNetworking 3.0 将图像上传到服务器。

这是我的代码:

AFHTTPSessionManager *manager = [AFHTTPSessionManager manager];
    [[manager POST:setUrl parameters:parameters constructingBodyWithBlock:^(id<AFMultipartFormData>  _Nonnull formData)
    
        //Current date with image name
        NSDateFormatter *dateFormatter=[[NSDateFormatter alloc] init];
        [dateFormatter setDateFormat:@"yyyy-MM-dd HH:mm:ss a"];
        [formData appendPartWithFileData:image name:namePara fileName:[NSString stringWithFormat:@"img_%@",[dateFormatter stringFromDate:[NSDate date]]] mimeType:@"image/png"];
        progress:nil
        success:^(NSURLSessionDataTask * _Nonnull task, id  _Nonnull responseObject)
        
            NSLog(@"%@",responseObject);
            [GMDCircleLoader hideFromView:self.view animated:YES];
            NSMutableDictionary *dir = [[NSMutableDictionary alloc]initWithDictionary:responseObject];
            if([dir valueForKey:@"error"])
            
                UIAlertController *alert = [[singletone sharedManager]showAlert:NSLocalizedString(@"SIGNIN", nil) :[NSString stringWithFormat: @"%@",[dir valueForKey:@"error"]] ];
                [self.parentViewController presentViewController:alert animated:YES completion:nil];
            
            else
            
                //Successfull
                UIAlertController *alertController = [UIAlertController alertControllerWithTitle:NSLocalizedString(@"REGISTRATION", nil) message:[dir valueForKey:@"success"] preferredStyle:UIAlertControllerStyleAlert];
                UIAlertAction* ok = [UIAlertAction actionWithTitle:NSLocalizedString(@"OK", nil) style:UIAlertActionStyleCancel handler:^(UIAlertAction * action)
                
                    [self.navigationController popViewControllerAnimated:YES];
                ];
            [alertController addAction:ok];
            [self presentViewController:alertController animated:YES completion:nil];
            
            NSLog(@"response object : %@",responseObject);
         failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error)                         NSLog(@"failure : %@",error.localizedDescription);
    ]resume];

它将进入成功块并出现 error : error In Image Uploading。我也尝试从 Postman 检查我的 API 响应,但从 Postman 可以正常工作。这段代码有什么问题?

【问题讨论】:

您能否添加一个邮递员截图,API 接受文件为 base64 或简单文件 对不起,我不能。但我可以告诉你所有的描述。我必须在邮递员中发送的图像是“文件”类型。并使用其他参数,例如名称,地址..等。我得到的响应是“成功”:“交付注册成功” 【参考方案1】:

试试下面的代码,它与 AFNetworking 3.0 一起工作:

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



    manager.responseSerializer = [AFJSONResponseSerializer serializerWithReadingOptions:NSJSONReadingAllowFragments];


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

                                        if (profile_pic.length!=0) 

                                            [formData appendPartWithFileData:imageData name:@"profile_pic" fileName:@"ProfilePic" mimeType:@"image/jpeg"];
                                        


                                     error:nil];

    NSURLSessionUploadTask *uploadTask;
    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

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


                      
                      else
                      

                      
                  ];

    [uploadTask resume];

【讨论】:

我得到响应成功。但在服务器上,我发送时未找到图像名称,即 profilepic 只要确认你的参数名称(name:@"profile_pic")是正确的 是的,我符合该参数。但奇怪的是,使用我的原始参数它不起作用,但使用你的参数它起作用。但未在服务器上显示图像名称。【参考方案2】:

你试试这个

manager.responseSerializer.acceptableContentTypes = [NSSet setWithObject:@"text/plain"];

【讨论】:

我正在尝试使用 manager.responseSerializer.acceptableContentTypes = [NSSet setWithObject:@"application/json"];但它仍然没有上传。并且还给我错误 BSMachError: (os/kern) invalid capability (20) _BSMachError: (os/kern) invalid name (15) ***.com/questions/32899586/…【参考方案3】:

您需要将 requestSerializer 设置为 @"multipart/form-data" for @"Content-Type"。

AFHTTPSessionManager *manager = [[AFHTTPSessionManager alloc]initWithSessionConfiguration:[NSURLSessionConfiguration defaultSessionConfiguration]];
    manager.requestSerializer = [AFHTTPRequestSerializer serializer];


    manager.responseSerializer=[AFJSONResponseSerializer serializer];

    NSString *contentType = [NSString stringWithFormat:@"multipart/form-data"];
    [manager.requestSerializer setValue:contentType forHTTPHeaderField:@"Content-Type"];


    [manager POST:setUrl parameters:parameters constructingBodyWithBlock:^(id<AFMultipartFormData>  _Nonnull formData) 
        NSDateFormatter *dateFormatter=[[NSDateFormatter alloc] init];
        [dateFormatter setDateFormat:@"yyyy-MM-dd HH:mm:ss a"];
        [formData appendPartWithFileData:image name:namePara fileName:[NSString stringWithFormat:@"img_%@",[dateFormatter stringFromDate:[NSDate date]]] mimeType:@"image/png"];


     progress:^(NSProgress * _Nonnull uploadProgress) 

     success:^(NSURLSessionDataTask * _Nonnull task, id  _Nullable responseObject) 

       NSLog(@"%@",responseObject);
            [GMDCircleLoader hideFromView:self.view animated:YES];
            NSMutableDictionary *dir = [[NSMutableDictionary alloc]initWithDictionary:responseObject];
            if([dir valueForKey:@"error"])
            
                UIAlertController *alert = [[singletone sharedManager]showAlert:NSLocalizedString(@"SIGNIN", nil) :[NSString stringWithFormat: @"%@",[dir valueForKey:@"error"]] ];
                [self.parentViewController presentViewController:alert animated:YES completion:nil];
            
            else
            
                //Successfull
                UIAlertController *alertController = [UIAlertController alertControllerWithTitle:NSLocalizedString(@"REGISTRATION", nil) message:[dir valueForKey:@"success"] preferredStyle:UIAlertControllerStyleAlert];
                UIAlertAction* ok = [UIAlertAction actionWithTitle:NSLocalizedString(@"OK", nil) style:UIAlertActionStyleCancel handler:^(UIAlertAction * action)
                
                    [self.navigationController popViewControllerAnimated:YES];
                ];
            [alertController addAction:ok];
            [self presentViewController:alertController animated:YES completion:nil];
            
            NSLog(@"response object : %@",responseObject);
     failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) 
        NSLog(@"error: %@", error.localizedDescription);

    ];

【讨论】:

还没有完成。 error : "上传图片出错";【参考方案4】:
NSData *nsdataFromBase64String = [[NSData alloc] initWithBase64EncodedString:imageBytes options:0];
NSMutableDictionary *parameters = [NSMutableDictionary dictionary];   

AFHTTPSessionManager *manager = [[AFHTTPSessionManager alloc] initWithBaseURL:[NSURL URLWithString:stringURL]];// Your API

    [manager POST:stringURL parameters:parameters constructingBodyWithBlock:^(id<AFMultipartFormData> formData)
    
        //do not put image inside parameters dictionary as I did, but append it!
        [formData appendPartWithFileData:nsdataFromBase64String name:fIds fileName:fileN mimeType:@"image/jpeg"];

    
    success:^(NSURLSessionDataTask *task, id responseObject)
     
         imgRes=@"success";
         //here is place for code executed in success case
     
    failure:^(NSURLSessionDataTask *task, NSError *error)
    
        imgRes=@"fail";
         //here is place for code executed in error case
     ];

在我的最后完美运行

这是您在 Postman 中使用的内容

【讨论】:

imageBytes 是 nsdata 吗? 是的,首先我从服务器获取 imageBytes。我将其改回 NSData 以将图像同步回服务器 我得到了原因:'无效参数不令人满意:body 你能告诉我,如果我从相册或相机中选择图片,如何获取图片 URL? 是的。你 ri8。我在邮递员中使用这种方式【参考方案5】:
NSData *nsdataFromBase64String = [[NSData alloc] initWithBase64EncodedString:"your image as base64 encoded" options:0];

NSDictionary *parameters = [NSMutableDictionary dictionary];

parameters = [NSDictionary dictionaryWithObjectsAndKeys:@"wr34", @"delivery_company_name", @"uname", @"user_name", @"123456789", @"contact_info", @"test1342@test.com", @"email",@"123456", @"password",@"SUV", @"car_type",@"White", @"car_color",@"GJ-1AE-2255", @"car_plate_no",@"43345dw", @"car_reg_no",@"123454", @"license_no",@"Model", @"car_model",@"location", @"location",@"4.3", @"latitude",@"8.7", @"longitude",@"notes", @"deliver_terms_conditions",@"notes", @"notes", nil];

AFHTTPSessionManager *manager = [[AFHTTPSessionManager alloc] initWithBaseURL:[NSURL URLWithString:stringURL]];
manager.responseSerializer = [AFJSONResponseSerializer serializer];
manager.requestSerializer = [AFJSONRequestSerializer serializer];

[manager POST:stringURL parameters:parameters constructingBodyWithBlock:^(id<AFMultipartFormData> formData)
 
     //do not put image inside parameters dictionary as I did, but append it!
     [formData appendPartWithFileData:nsdataFromBase64String name:@"ToyotaSupra" fileName:@"ToyotaSupra" mimeType:@"image/png"];

 
      success:^(NSURLSessionDataTask *task, id responseObject)
 
     imgRes=@"success";
     //here is place for code executed in success case
 
      failure:^(NSURLSessionDataTask *task, NSError *error)
 
     imgRes=@"fail";
     //here is place for code executed in error case
 ];

下载工作代码

https://www.dropbox.com/s/3ot6kpiqs3pn2h0/AFNetwork.zip?dl=0

【讨论】:

您使用的是哪个版本的afnetworking? [manager POST:stringURL parameters:parameters constructionBodyWithBlock:^(id formData) 从您的代码中被弃用。我正在尝试使用相同的代码,它工作正常。但在这个弃用的警告之后。它不工作。

以上是关于使用 AFNetworking 3.0 上传图像 [关闭]的主要内容,如果未能解决你的问题,请参考以下文章

使用 AFMultipartFormData AFNetworking 3.0 上传图像

从 imagePickerController AFNetWorking 3.0 上传图像到服务器

AFNetworking 3.0 上传图片

AFNetworking 3.0 中带有图像和其他参数的多部分数据

当应用程序移动到后台时,AFNetworking 3.0 继续上传

AFNetworking 3.0 后台上传不起作用