第一个图片是用AFN请求的即
AFHTTPSessionManager *manager = [weakSelf managerInit];
url = [NSString urlCode:url];
return [manager POST:url parameters:parameter constructingBodyWithBlock:^(id<AFMultipartFormData> formData) {
// 图片
if (pictureArrays.count) {
for (int i = 0; i < pictureArrays.count; i++) {
UIImage *image = pictureArrays[i];
NSData *data = UIImageJPEGRepresentation(image,0.1);
NSDateFormatter *formatter = [[NSDateFormatter alloc] init];
formatter.dateFormat = @"yyyyMMddHHmmss";
NSString *str = [formatter stringFromDate:[NSDate date]];
NSString *fileName = [NSString stringWithFormat:@"%@photo_%d.jpg",str, i];
[formData appendPartWithFileData:data name:@"photo" fileName:fileName mimeType:@"image/jpeg"];
}
}
// 语音:
if (audioData) {
NSDateFormatter *formatter = [[NSDateFormatter alloc]init];
formatter.dateFormat = @"yyyyMMddHHmmss";
NSString *str = [formatter stringFromDate:[NSDate date]];
NSString *audioName = [NSString stringWithFormat:@"%@.mp3", str];
[formData appendPartWithFileData:audioData name:@"Audio" fileName:audioName mimeType:@"mp3"];
}
} success:^(NSURLSessionDataTask *task, id responseObject) {
if (responseObject) {
success(responseObject);
}
} failure:^(NSURLSessionDataTask *task, NSError *error) {
failure(error);
}];
请求成功的图片
第二种是用NSURLSession做的
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:urlString] cachePolicy:0 timeoutInterval:60];
NSString *myBoundary = mhfBoundary();
[request setValue:[NSString stringW
ithFormat:@"multipart/form-data; boundary=%@",myBoundary] forHTTPHeaderField:@"Content-Type"];
[self addHeaderAccessToken:request];
request.HTTPMethod = @"POST";
NSMutableData *totalData = [NSMutableData data];
// 拼接文件格式:
// . 遍历普通参数字典,拼接普通参数的上传格式.
[parameters enumerateKeysAndObjectsUsingBlock:^(id _Nonnull key, id _Nonnull obj, BOOL * _Nonnull stop) {
// 拼接普通参数的上传格式.
// 1. 普通参数上边界
NSMutableString *headerStrM = [NSMutableString stringWithFormat:@"\r\n--%@\r\n",myBoundary];
// 服务器接收参数的key值.
[headerStrM appendFormat:@"Content-Disposition: form-data; name=\"%@\"\r\n\r\n",key];
// 将普通参数上边界添加到请求体中
[totalData appendData:[headerStrM dataUsingEncoding:NSUTF8StringEncoding]];
// 2. 普通参数内容
NSString * objValue = [NSString stringWithFormat:@"%@",obj];
NSData *parameterData = [objValue dataUsingEncoding:NSUTF8StringEncoding];
// 将普通参数内容添加到请求体中
[totalData appendData:parameterData];
}];
// 文件的上边界
// 1. 遍历文件参数字典,拼接文件参数格式.
if (pictureArrays.count) {
for (int i = 0; i < pictureArrays.count; i++) {
UIImage *image = pictureArrays[i];
NSMutableString *headerStrM = [NSMutableString stringWithFormat:@"\r\n--%@\r\n",myBoundary];
NSData *data = UIImageJPEGRepresentation(image,0.1);
NSDateFormatter *formatter = [[NSDateFormatter alloc] init];
formatter.dateFormat = @"yyyyMMddHHmmss";
NSString *str = [formatter stringFromDate:[NSDate date]];
NSString *fileName = [NSString stringWithFormat:@"%@photo_%d.jpg",str, i];
[headerStrM appendFormat:@"Content-Disposition: form-data; name=\"photo\"; filename=\"%@\"\r\n",fileName];
[headerStrM appendFormat:@"Content-Type: image/jpeg\r\n\r\n"];
[totalData appendData:[headerStrM dataUsingEncoding:NSUTF8StringEncoding]];
[totalData appendData:data];
}
}
if (audioData) {
NSMutableString *headerStrM = [NSMutableString stringWithFormat:@"\r\n--%@\r\n",myBoundary];
NSDateFormatter *formatter = [[NSDateFormatter alloc]init];
formatter.dateFormat = @"yyyyMMddHHmmss";
NSString *str = [formatter stringFromDate:[NSDate date]];
NSString *audioName = [NSString stringWithFormat:@"%@.mp3", str];
[headerStrM appendFormat:@"Content-Disposition: form-data; name=\"Audio\"; filename=\"%@\"\r\n",audioName];
[headerStrM appendFormat:@"Content-Type: mp3\r\n\r\n"];
[totalData appendData:[headerStrM dataUsingEncoding:NSUTF8StringEncoding]];
[totalData appendData:audioData];
}
// 下边界内容
NSMutableString *footerStrM = [NSMutableString stringWithFormat:@"\r\n--%@--",myBoundary];
// 将下边界内容添加到请求体中
[totalData appendData:[footerStrM dataUsingEncoding:NSUTF8StringEncoding]];
urlRequest.HTTPBody = totalData;
urlRequest.HTTPMethod = @"POST";
NSURLSessionDataTask *dataTask = [[NSURLSession sharedSession] dataTaskWithRequest:urlRequest completionHandler:^(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error) {
if (success == nil) return;
NSHTTPURLResponse *httpResponse = (NSHTTPURLResponse *) response;
if (httpResponse.statusCode == 200) {
if (data != nil) {
//NSJSONReadingMutableContainers
id dict = [NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingAllowFragments error:&error];
if (dict) {
mDispatchMainAsyncSafe(^{
success(dict,response);
});
}else{
// 返回Json的data为H5页面,或其他
[self baseFailure:[[NSError alloc]init] failureBlock:failure];
}
}else {
// 返回data二进制数据为空,表示响应失败
if (failure == nil) return;
[self baseFailure:error failureBlock:failure];
}
}else{
// 服务器返回 302,500,404等
[self baseFailure:error failureBlock:failure];
}
}];
[dataTask resume];
两个返回的一个返回200,一个返回305,返回错误的发现Content-Type是一个问题,应该加boundary
且一个请求接口的boundary应该都是一样的分割boundary,如果每次不一样则报错.
所以表单请求一定要注意Content-Type和boundary是否正确