服務器要求使用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;