新公司需要上传多张照片,类似于电商的评价图片,上次使用AFNetworking上传图片是两年前了.网上看了一些资料,看到有可以直接拿来用的,我就copy过来了,省心省力,贴上从网上找的代码
## 上传多张图片
NSArray * _imageArr = @[@"1",@"2",@"3"];
AFHTTPSessionManager *manager = [AFHTTPSessionManager manager];
manager.requestSerializer.timeoutInterval = 20;
manager.responseSerializer.acceptableContentTypes = [NSSet setWithArray:@[@"text/plain",@"multipart/form-data"]];
[manager POST:@"http://192.168.0.105:8080/miracle/Upload.action" parameters:nil constructingBodyWithBlock:^(id<AFMultipartFormData> _Nonnull formData) {
for (int i=0; i<_imageArr.count; i++) {
UIImage * image =[UIImage imageNamed:_imageArr[I]];
NSDate *date = [NSDate date];
NSDateFormatter *formormat = [[NSDateFormatter alloc]init];
[formormat setDateFormat:@"HHmmss"];
NSString *dateString = [formormat stringFromDate:date];
NSString *fileName = [NSString stringWithFormat:@"%@.png",dateString];
NSData *imageData = UIImageJPEGRepresentation(image, 1);
double scaleNum = (double)300*1024/imageData.length;
NSLog(@"图片压缩率:%f",scaleNum);
if(scaleNum <1){
imageData = UIImageJPEGRepresentation(image, scaleNum);
}else{
imageData = UIImageJPEGRepresentation(image, 0.1);
}
[formData appendPartWithFileData:imageData name:@"files" fileName:fileName mimeType:@"image/jpg/png/jpeg"];
}
} progress:^(NSProgress * _Nonnull uploadProgress) {
NSLog(@"---%@",uploadProgress);
} success:^(NSURLSessionDataTask * _Nonnull task, id _Nullable responseObject) {
NSLog(@"`````````%@",responseObject);
NSDictionary *datas = [NSJSONSerialization JSONObjectWithData:responseObject options:NSJSONReadingMutableContainers | NSJSONReadingMutableLeaves error:nil];
NSLog(@"请求成功%@",datas);
} failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {
}];
下面是我自己使用的时候的代码
/*
此段代码如果需要修改,可以调整的位置
1. 把upload.php改成网站开发人员告知的地址
2. 把file改成网站开发人员告知的字段名
*/
NSMutableArray *tempArray = [NSMutableArray array] ;
NSDictionary *dic = @{@"param1":[NSString stringWithFormat:@"%lld",self.param1],@"param2":[NSString stringWithFormat:@"%lld",self.param2] ,};
[tempArray addObject:dic];
NSString * tempString = [self arrayToJSONString:tempArray];
NSDictionary *dict = @{@"param3":tempString,@"param4":[NSString stringWithFormat:@"%lld",self.param4] };
// 基于AFN3.0+ 封装的HTPPSession句柄
AFHTTPSessionManager *manager = [AFHTTPSessionManager manager];
manager.requestSerializer.timeoutInterval = 20;
manager.responseSerializer.acceptableContentTypes = [NSSet setWithObjects:@"text/plain", @"multipart/form-data", @"application/json", @"text/html", @"image/jpeg", @"image/png", @"application/octet-stream", @"text/json", nil];
//formData: 专门用于拼接需要上传的数据,在此位置生成一个要上传的数据体
[manager POST:URL parameters:dict constructingBodyWithBlock:^(id<AFMultipartFormData> _Nonnull formData) {
// formData: 专门用于拼接需要上传的数据,在此位置生成一个要上传的数据体
// 这里的_photoArr是你存放图片的数组
for (int i = 0; i < _photosArr.count; i++) {
UIImage *image = _photosArr[i];
NSData *imageData = UIImageJPEGRepresentation(image, 1.0);
// 在网络开发中,上传文件时,是文件不允许被覆盖,文件重名
// 要解决此问题,
// 可以在上传时使用当前的系统事件作为文件名
NSDateFormatter *formatter = [[NSDateFormatter alloc] init];
// 设置时间格式
[formatter setDateFormat:@"yyyyMMddHHmmss"];
NSString *dateString = [formatter stringFromDate:[NSDate date]];
NSString *fileName = [NSString stringWithFormat:@"%@%d.jpg", dateString,i];
/*
*该方法的参数
1. appendPartWithFileData:要上传的照片[二进制流]
2. name:对应网站上[upload.php中]处理文件的字段(比如upload)
3. fileName:要保存在服务器上的文件名
4. mimeType:上传的文件的类型
*/
if (i == 0) {
[formData appendPartWithFileData:imageData name:@"eReceiptImg" fileName:fileName mimeType:@"image/jpeg"];
}else{
[formData appendPartWithFileData:imageData name:[NSString stringWithFormat:@"eReceiptImg%d",i+1] fileName:fileName mimeType:@"image/jpeg"];
}
//
}
} progress:^(NSProgress * _Nonnull uploadProgress) {
//上传进度
// @property int64_t totalUnitCount; 需要下载文件的总大小
// @property int64_t completedUnitCount; 当前已经下载的大小
//
// 给Progress添加监听 KVO
NSLog(@"%f",1.0 * uploadProgress.completedUnitCount / uploadProgress.totalUnitCount);
// 回到主队列刷新UI,用户自定义的进度条
dispatch_async(dispatch_get_main_queue(), ^{
// self.progressView.progress = 1.0 *
// uploadProgress.completedUnitCount / uploadProgress.totalUnitCount;
[SVProgressHUD showProgress:(1.0 * uploadProgress.completedUnitCount / uploadProgress.totalUnitCount) status:@"保存中..."];
});
} success:^(NSURLSessionDataTask * _Nonnull task, id _Nullable responseObject) {
[SVProgressHUD dismiss];
NSLog(@"```上传成功``` %@",responseObject);
NSDictionary *dict = (NSDictionary *)responseObject;
NSInteger inter = [dict[@"success"] integerValue];
NSString *alertSTR = dict[@"msg"];
if (inter == 1) {
[self.view makeToast:@"保存成功" duration:2 position:CSToastPositionCenter title:nil image:nil style:nil completion:^(BOOL didTap) {
if ([_delegate respondsToSelector:@selector(signOkClick:)]) {
[_delegate signOkClick:self];
}
[self.navigationController popViewControllerAnimated:YES];
}];
}else{
[self.view makeToast:alertSTR duration:2 position:CSToastPositionCenter];
}
} failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {
[SVProgressHUD showErrorWithStatus:@"上传失败"];
[SVProgressHUD dismissWithDelay:1.5];
}];
说说我在使用的时候遇到的问题
我上传了,我这边显示上传成功,后台可以收到parameters
的参数,但是收不到图片.开始找原因
1.上网看了下资料,说是下面的name不一样,但是确实和后台商量好的,字段没有错.排除这个原因.
2.自己断点看了下formData的状态,发现没有下面标的这个NSObject,就想是不是对象被提前释放了,我又看了公司以前的项目,发现他是有的,其他代码基本一样,但是AFNetworking用的是3.0,我用的是3.1.0,我就把我的版本改成3.0,改过之后确实出现了NSObject.具体原因未知但是结果是后台还是收不到
3.没办法了,我去找后台的同学联调,联调的结果是后台在收到请求之后就不往下编译了,在解析我上传的
parameters
停住了,想到了另外一个原因,是不是我上传的参数的格式不对,导致解析不了,造成失败,结果确实是这样,我这边上传的是字典,后台要的是json字符串.通过下面的方法将参数转成json字符串,问题得到解决
注意:这一段就是我改动的地方,有三个参数,需要将两个参数放在字典里然后再放在数组里,最后生成json字符串,在和另外一个一起放字典里上传
NSMutableArray *tempArray = [NSMutableArray array] ;
NSDictionary *dic = @{@"param1":[NSString stringWithFormat:@"%lld",self.param1],@"param2":[NSString stringWithFormat:@"%lld",self.param2] ,};
[tempArray addObject:dic];
NSString * tempString = [self arrayToJSONString:tempArray];
//dict是请求的参数parameters
NSDictionary *dict = @{@"param3":tempString,@"param4":[NSString stringWithFormat:@"%lld",self.param4] };
- (NSString *)arrayToJSONString:(NSArray *)array
{
NSError *error = nil;
// NSMutableArray *muArray = [NSMutableArray array];
// for (NSString *userId in array) {
// [muArray addObject:[NSString stringWithFormat:@"\"%@\"", userId]];
// }
NSData *jsonData = [NSJSONSerialization dataWithJSONObject:array options:NSJSONWritingPrettyPrinted error:&error];
NSString *jsonString = [[NSString alloc] initWithData:jsonData encoding:NSUTF8StringEncoding];
// NSString *jsonTemp = [jsonString stringByReplacingOccurrencesOfString:@"\n" withString:@""];
// NSString *jsonResult = [jsonTemp stringByReplacingOccurrencesOfString:@" " withString:@""];
// NSLog(@"json array is: %@", jsonResult);
return jsonString;
}
网友评论