AFNetworking PUT方式 form-data表单格式上传图片

服务器要求使用PUT方式上传图片, 采用网页端的表单格式进行提交,由于之前很少使用PUT请求方式,只接触过POST form-data方式和base64方式,调试了半天终于解决了,现在将方法拿出来,给大家参考,欢迎指正!

+ (void)putImageToServer{
    NSString * filePath = [[NSBundle mainBundle] pathForResource:@"image.jpg" ofType:nil];
    NSURL * fileURL = [NSURL fileURLWithPath:filePath];
    
//CBNetworkManager继承自 AFHttpURLSessionManaager
    [NetworkManager put_uploadFileWithURLString:@"http://domain/goods/goods/uploadGoods Image?id=10002316&access_token=a351d9bde-0aqd-4f61-91s4-9af4d5d6664c" rename:@"apple.jpg" fromFile:fileURL orFromData:nil progressBlock:^(float progress) {
        CBNSLog(@"上传文件进度%f", progress);
    } callBack:^(NSURLSessionTask *task, id response, NSError *error) {
        if (error) {
            CBNSLog(@"error = %@", error);
        }else {
            NSString * string = [[NSString alloc]initWithData:response encoding:NSUTF8StringEncoding];
            CBNSLog(@"success = %@", string);
        }
    }];   
}
// 上传图片方法,支持文件地址上传和二进制数据上传两种方式
+ (void)put_uploadFileWithURLString:(NSString *)URLString
                             rename:(NSString *)rename
                           fromFile:(NSURL *)fileURL
                         orFromData:(NSData *)bodyData
                      progressBlock:(ProgressBlock)progressBlock
                           callBack:(RequestCallBack)callback
+ (void)put_uploadFileWithURLString:(NSString *)URLString
                             rename:(NSString *)rename
                           fromFile:(NSURL *)fileURL
                         orFromData:(NSData *)bodyData
                      progressBlock:(ProgressBlock)progressBlock
                           callBack:(RequestCallBack)callback{
    
    NSMutableURLRequest * request = [[AFHTTPRequestSerializer serializer] multipartFormRequestWithMethod:@"PUT" URLString:URLString parameters:nil constructingBodyWithBlock:^(id  _Nonnull formData) {
        [formData appendPartWithFileURL:fileURL name:@"file" fileName:rename mimeType:@"image/jpg" error:nil];
        
    } error:nil];
    
    void(^completionBlock)(id responseObject,NSError * error) = ^(id responseObject,NSError * error) {
        if (callback) {
            if (error) {
                callback(nil,nil,error);
            }
            else if (responseObject){
                callback(nil, responseObject,nil);
            }
        }
    };
    
// 方式一: 直接通过文件地址上传
    if (fileURL) {
        // 使用表单的方式进行提交, uploadTaskWithStreamedRequest  另一个直接上传FileURL 的方式,会报错500
        NSURLSessionUploadTask * task =  [[CBNetworkManager sharedManager] uploadTaskWithStreamedRequest:request progress:^(NSProgress * _Nonnull uploadProgress) {
            if (progressBlock) {
                progressBlock(uploadProgress.completedUnitCount / uploadProgress.totalUnitCount);
            }
        } completionHandler:^(NSURLResponse * _Nonnull response, id  _Nullable responseObject, NSError * _Nullable error) {
            completionBlock(responseObject, error);
        }];
        
        [task resume];
    }
    
// 方式二: 将文件转成二进制上传,该方式文件后台接收不到,不知道为啥,建议使用第一种
// 还有可能出现: `Domain=NSCocoaErrorDomain Code=3840 "JSON text did not start with array or object and option to allow fragments not set ` 错误,要指定响应接收类型
//        [CBNetworkManager sharedManager].requestSerializer = [AFHTTPRequestSerializer serializer];
//        [CBNetworkManager sharedManager].responseSerializer = [AFHTTPResponseSerializer serializer];


    if (bodyData) {
        [[CBNetworkManager sharedManager] uploadTaskWithRequest:request fromData:bodyData progress:^(NSProgress * _Nonnull uploadProgress) {
            if (progressBlock) {
                progressBlock(uploadProgress.completedUnitCount / uploadProgress.totalUnitCount);
            }
        } completionHandler:^(NSURLResponse * _Nonnull response, id  _Nullable responseObject, NSError * _Nullable error) {
            completionBlock(responseObject, error);
        }];
    }
    
}

调用系统NSURLSession的方法如下:

/* Creates an upload task with the given request. The body of the request will be created from the file referenced by fileURL */

  • (NSURLSessionUploadTask *)uploadTaskWithRequest:(NSURLRequest *)request fromFile:(NSURL *)fileURL;

/* Creates an upload task with the given request. The body of the request is provided from the bodyData. */

  • (NSURLSessionUploadTask *)uploadTaskWithRequest:(NSURLRequest *)request fromData:(NSData *)bodyData;

你可能感兴趣的