服务器要求使用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<AFMultipartFormData> _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;