iOS 自己封装一个Mutipart网络请求
作者:互联网
文章目录
iOS 自己拼装Multipart网络请求
什么是Mutipart网络请求
mutipart网络请求是一种post网络请求,主要用来上传大文件,如图片、音视频数据等;
什么条件下需要自己拼装mutipart网络请求
一般的项目中我们的网络请求都是基于第三方的网络框架,如AFNetworking,但是如果我们在写SDK或者demo时,不想引用太多的第三方,就需要自己去拼装mutipart请求;
基于AFNetwoking的mutipart网络请求
- (nullable NSURLSessionDataTask *)POST:(NSString *)URLString
parameters:(nullable id)parameters
constructingBodyWithBlock:(nullable void (^)(id <AFMultipartFormData> formData))block
success:(nullable void (^)(NSURLSessionDataTask *task, id _Nullable responseObject))success
failure:(nullable void (^)(NSURLSessionDataTask * _Nullable task, NSError *error))failure DEPRECATED_ATTRIBUTE;
通过@protocol AFMultipartFormData
中的以下协议向requet body中添加数据即可;
- (void)appendPartWithFileData:(NSData *)data
name:(NSString *)name
fileName:(NSString *)fileName
mimeType:(NSString *)mimeType;
代码示例
[manager POST:URLString parameters:parameters constructingBodyWithBlock:^(id<AFMultipartFormData> _Nonnull formData) {
switch (fileType) {
case DBUploadFileTypeWAV:{
NSData *data = [NSData dataWithContentsOfFile:filePath];
NSString * nameStr = [NSString stringWithFormat:@"%@.wav",name];
[formData appendPartWithFileData:data name:@"file" fileName:nameStr mimeType:@"audio/*"];
}
break;
case DBUploadFileTypeMp3:{
NSData *data = [NSData dataWithContentsOfFile:filePath];
NSString * nameStr = [NSString stringWithFormat:@"%@.mp3",name];
[formData appendPartWithFileData:data name:@"file" fileName:nameStr mimeType:@"audio/*"];
}
break;
case DBUploadFileTypeImage:{
NSString * nameStr = [NSString stringWithFormat:@"%@.png",name];
[formData appendPartWithFileData:imageData name:@"file" fileName:nameStr mimeType:@"png"];
}
break;
}
} progress:^(NSProgress * _Nonnull uploadProgress) {
//上传进度
dispatch_sync(dispatch_get_main_queue(), ^{
progress ? progress(uploadProgress) : nil;
});
} success:^(NSURLSessionDataTask * _Nonnull task, id _Nullable responseObject) {
success ? success(responseObject) : nil;
} failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {
failure ? failure(error) : nil;
}];
基于UNSURLSession创建的Mutipart请求
1.预定义封装Mutipart需要的格式
定义post请求数据的分割线 DBUploadBoundary
static NSString *DBUploadBoundary = @"DBUploadBoundary";
定义宏定义的编码
#define DBEncode(string) [string dataUsingEncoding:NSUTF8StringEncoding]
定义换行
#define DBEnter [@"\r\n" dataUsingEncoding:NSUTF8StringEncoding]
拼接mutipart请求
-(NSData *)getDataWithPath:(NSString *)path params:(NSDictionary *)params {
NSMutableData *data = [NSMutableData data];
[params enumerateKeysAndObjectsUsingBlock:^(id _Nonnull key, id _Nonnull obj, BOOL * _Nonnull stop) {
// 拼接普通参数的上传格式.
// 1. 普通参数上边界
NSMutableString *headerStrM = [NSMutableString stringWithFormat:@"\r\n--%@\r\n",DBUploadBoundary];
// 服务器接收参数的key值.
[headerStrM appendFormat:@"Content-Disposition: form-data; name=\"%@\"\r\n\r\n",key];
// 将普通参数上边界添加到请求体中
[data appendData:[headerStrM dataUsingEncoding:NSUTF8StringEncoding]];
// 2. 普通参数内容
NSString * objValue = [NSString stringWithFormat:@"%@",obj];
NSData *parameterData = [objValue dataUsingEncoding:NSUTF8StringEncoding];
// 将普通参数内容添加到请求体中
[data appendData:parameterData];
}];
[data appendData:DBEnter];
[data appendData:DBEncode(@"--")];
[data appendData:DBEncode(DBUploadBoundary)];
[data appendData:DBEnter];
[data appendData:DBEncode(@"Content-Disposition: form-data; name=\"file\"; filename=\"record.wav\"")];
[data appendData:DBEnter];
[data appendData:DBEncode(@"Content-Type: audio/wav")];
[data appendData:DBEnter];
[data appendData:DBEnter];
NSData *wavData = [NSData dataWithContentsOfFile:path];
[data appendData:wavData];
[data appendData:DBEnter];
[data appendData:DBEncode(@"--")];
[data appendData:DBEncode(DBUploadBoundary)];
[data appendData:DBEncode(@"--")];
[data appendData:DBEnter];
return data;
}
3.发起一个mutipart网络请求
代码示例
NSData *data = [self getDataWithPath:path params:mutableDict];
NSURLSession *session = [NSURLSession sessionWithConfiguration:[NSURLSessionConfiguration defaultSessionConfiguration] delegate:self delegateQueue:[NSOperationQueue mainQueue]];
//6、获取上传的数据
NSData *uploadData = data;
//7、创建上传任务 上传的数据来自getData方法
NSURLSessionUploadTask *task = [session uploadTaskWithRequest:request fromData:uploadData completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) {
if (error) {
failureBlock(error);
}else {
NSDictionary *contentDict = [NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingMutableContainers error:nil];//转换数据格式
successBlock(contentDict);
}
}];
[task resume];
标签:封装,请求,Mutipart,iOS,NSString,NSData,appendData,data,name 来源: https://blog.csdn.net/SunFlowerInRain/article/details/104793519