AFNetworking 文件上传Data,File图片,文件等上传
2016-03-21 13:17
483 查看
使用AFNetworking上传图片,(可一次上传多张图片,包含不同类型png, jpeg)
使用AFNetworking上传视频
AFHTTPRequestOperationManager *manager = [AFHTTPRequestOperationManager manager];
AFHTTPRequestOperation *operation = [manager POST:mutPath
parameters:param
constructingBodyWithBlock:^(id<AFMultipartFormData> formData) {
if (mediaDatas.count > 0) {
NSObject *firstObj = [mediaDatas objectAtIndexSafe:0];
if ([firstObj isKindOfClass:[UIImage class]]) { // 图片
for(NSInteger i=0; i<mediaDatas.count; i++) {
UIImage *eachImg = [mediaDatas objectAtIndexSafe:i];
//NSData *eachImgData = UIImagePNGRepresentation(eachImg);
NSData *eachImgData = UIImageJPEGRepresentation(eachImg, 0.5);
[formData appendPartWithFileData:eachImgData name:[NSString stringWithFormat:@"img%d", i+1] fileName:[NSString stringWithFormat:@"img%d.jpg", i+1] mimeType:@"image/jpeg"];
}
}else { // 视频
ALAsset *asset = [mediaDatas objectAtIndexSafe:0];
NBLog(@"asset=%@, representation=%@, url=%@", asset, [asset defaultRepresentation], [asset defaultRepresentation].url);
if (asset !=nil) {
NSString *videoPath = [NSDocumentsPath stringByAppendingPathComponent:[NSString stringWithFormat:@"%d.mov", 0]]; // 这里直接强制写一个即可,之前计划是用i++来区分不明视频
NSURL *url = [NSURL fileURLWithPath:videoPath];
NSError *theErro =nil;
BOOL exportResult = [asset exportDataToURL:url error:&theErro];
NBLog(@"exportResult=%@", exportResult?@"YES":@"NO");
NSData *videoData = [NSData dataWithContentsOfURL:url];
[formData appendPartWithFileData:videoData name:@"video1" fileName:@"video1.mov" mimeType:@"video/quicktime"];
NBLog(@"method 2");
}
}
}
} success:^(AFHTTPRequestOperation *operation,id responseObject) {
NSDictionary *returnedDic = [XXBaseViewController parseResponseObj:responseObject];
NBLog(@"post Big success returnedDic=%@", returnedDic);
} failure:^(AFHTTPRequestOperation *operation, NSError *error) {
NBLog(@"post big file fail error=%@", error);
if (errorBlock) {
errorBlock(@{@"errorcode":@(error.code),@"errordomain":error.domain});
}
}];
[operation setUploadProgressBlock:^(NSUInteger bytesWritten,long long totalBytesWritten,long longtotalBytesExpectedToWrite)
{
NSLog(@"bytesWritten=%d, totalBytesWritten=%lld, totalBytesExpectedToWrite=%lld", bytesWritten, totalBytesWritten, totalBytesExpectedToWrite);
if (xxProgressView != nil) {
[xxProgressView setProgressViewTo:totalBytesWritten*1.0/totalBytesExpectedToWrite];
}
}];
1. 注意上面上传图片时时, 需要先转为NSData, 然后再执行
[formData appendPartWithFileData:eachImgData name:[NSString stringWithFormat:@"img%d", i+1] fileName:[NSString stringWithFormat:@"img%d.jpg",
i+1] mimeType:@"image/jpeg"];
执行这个方法时, name:部分是服务器用来解析的字段, 而fileName则是直接上传上去的图片, 注意一定要加 .jpg或者.png,(这个根据你得到这个imgData是通过jepg还是png的方式来获取决定)。 然后mimeType值也要与上面的类型对应, 网上看到有的说直接写成 @"image/*", 据说也是可以的, 没验证过。
但一定要注意的是这个fileName中.jpg和.png是一定要添加的。 否则服务器可能会推断这个图片的类型, 推断时就可能推断错误, 而使得图片上传上去后,显示不出来的问题。 我在做这个项目时就遇到了这样的问题, 现象就是有时上传成功,有时上传失败。 有时上传上去3张图,结果只显示2张图, 最后一张图显示不出来的, 可能就是因为服务器推断格式时推断错误。
2. 对于上面的视频文件, 这里使用的是ALAsset类型, 这个是通过
CTAssetsPickerController来选择手机相册中的视频文件的。
然后通过生成一个视频文件名及地址, 并通过一个写方法, 写到该路径下, 写文件如下。
- (BOOL) exportDataToURL: (NSURL*) fileURL error: (NSError**) error
{
[[NSFileManager defaultManager] createFileAtPath:[fileURL path] contents:nil attributes:nil];
NSFileHandle *handle = [NSFileHandle fileHandleForWritingToURL:fileURL error:error];
if (!handle) {
return NO;
}
ALAssetRepresentation *rep = [self defaultRepresentation];
uint8_t *buffer = calloc(BufferSize,sizeof(*buffer));
NSUInteger offset = 0, bytesRead = 0;
do {
@try {
bytesRead = [rep getBytes:buffer fromOffset:offset length:BufferSize error:error];
[handle writeData:[NSData dataWithBytesNoCopy:buffer length:bytesRead freeWhenDone:NO]];
offset += bytesRead;
}@catch (NSException *exception) {
free(buffer);
return NO;
}
}while (bytesRead > 0);
free(buffer);
return YES;
}
把视频写入后,再通过NSData来取出这个视频的数据。 并添加到这个AFHttpRequestOperation的Body中, 进行传输。
(估计这里可能有更好的办法来实现这个功能, 因为上面这个写入文件后,再转成NSData感觉有些繁琐,因为我曾尝试过其它方法,如通过ALAsset来获取到这个视频文件的url地址, 然后再通过NSData直接取这个地址,结果发现上传给后台后, 后台并不能识别到这个视频文件,后台能知道确实收到了视频数据,但可能某些原因,使得前端再次去获取该视频文件时,发现播放不了。具体原因可以再次去进行研究。
尝试过程如下:
A:
上传后, 后台仅获取到文本
ALAssetRepresentation *rep = [asset defaultRepresentation];
Byte *buffer = (Byte*)malloc(rep.size);
NSUInteger buffered = [rep getBytes:buffer fromOffset:0.0 length:rep.size error:nil];
NSData *videoData = [NSData dataWithBytesNoCopy:buffer length:buffered freeWhenDone:YES];
// [formData appendPartWithFormData:videoData name:@"video1"];
[formData appendPartWithFileData:videoData name:@"video1"fileName:@"video1.mov" mimeType:@"video/quicktime"];
尝试B:
通过NSURl来取到这个地址, 然后用NSData来取视频, 然后再把这个视频进行上传。
)
有兴趣的朋友可以继续研究下去。
注:上传视频时和上面的上传图片一样,需要指定这个.mov, 及video/quicktime 类型指定。 前面的方法中要进行存储到本地时, 文件名指定为%d.mov。
使用AFNetworking上传视频
AFHTTPRequestOperationManager *manager = [AFHTTPRequestOperationManager manager];
AFHTTPRequestOperation *operation = [manager POST:mutPath
parameters:param
constructingBodyWithBlock:^(id<AFMultipartFormData> formData) {
if (mediaDatas.count > 0) {
NSObject *firstObj = [mediaDatas objectAtIndexSafe:0];
if ([firstObj isKindOfClass:[UIImage class]]) { // 图片
for(NSInteger i=0; i<mediaDatas.count; i++) {
UIImage *eachImg = [mediaDatas objectAtIndexSafe:i];
//NSData *eachImgData = UIImagePNGRepresentation(eachImg);
NSData *eachImgData = UIImageJPEGRepresentation(eachImg, 0.5);
[formData appendPartWithFileData:eachImgData name:[NSString stringWithFormat:@"img%d", i+1] fileName:[NSString stringWithFormat:@"img%d.jpg", i+1] mimeType:@"image/jpeg"];
}
}else { // 视频
ALAsset *asset = [mediaDatas objectAtIndexSafe:0];
NBLog(@"asset=%@, representation=%@, url=%@", asset, [asset defaultRepresentation], [asset defaultRepresentation].url);
if (asset !=nil) {
NSString *videoPath = [NSDocumentsPath stringByAppendingPathComponent:[NSString stringWithFormat:@"%d.mov", 0]]; // 这里直接强制写一个即可,之前计划是用i++来区分不明视频
NSURL *url = [NSURL fileURLWithPath:videoPath];
NSError *theErro =nil;
BOOL exportResult = [asset exportDataToURL:url error:&theErro];
NBLog(@"exportResult=%@", exportResult?@"YES":@"NO");
NSData *videoData = [NSData dataWithContentsOfURL:url];
[formData appendPartWithFileData:videoData name:@"video1" fileName:@"video1.mov" mimeType:@"video/quicktime"];
NBLog(@"method 2");
}
}
}
} success:^(AFHTTPRequestOperation *operation,id responseObject) {
NSDictionary *returnedDic = [XXBaseViewController parseResponseObj:responseObject];
NBLog(@"post Big success returnedDic=%@", returnedDic);
} failure:^(AFHTTPRequestOperation *operation, NSError *error) {
NBLog(@"post big file fail error=%@", error);
if (errorBlock) {
errorBlock(@{@"errorcode":@(error.code),@"errordomain":error.domain});
}
}];
[operation setUploadProgressBlock:^(NSUInteger bytesWritten,long long totalBytesWritten,long longtotalBytesExpectedToWrite)
{
NSLog(@"bytesWritten=%d, totalBytesWritten=%lld, totalBytesExpectedToWrite=%lld", bytesWritten, totalBytesWritten, totalBytesExpectedToWrite);
if (xxProgressView != nil) {
[xxProgressView setProgressViewTo:totalBytesWritten*1.0/totalBytesExpectedToWrite];
}
}];
1. 注意上面上传图片时时, 需要先转为NSData, 然后再执行
[formData appendPartWithFileData:eachImgData name:[NSString stringWithFormat:@"img%d", i+1] fileName:[NSString stringWithFormat:@"img%d.jpg",
i+1] mimeType:@"image/jpeg"];
执行这个方法时, name:部分是服务器用来解析的字段, 而fileName则是直接上传上去的图片, 注意一定要加 .jpg或者.png,(这个根据你得到这个imgData是通过jepg还是png的方式来获取决定)。 然后mimeType值也要与上面的类型对应, 网上看到有的说直接写成 @"image/*", 据说也是可以的, 没验证过。
但一定要注意的是这个fileName中.jpg和.png是一定要添加的。 否则服务器可能会推断这个图片的类型, 推断时就可能推断错误, 而使得图片上传上去后,显示不出来的问题。 我在做这个项目时就遇到了这样的问题, 现象就是有时上传成功,有时上传失败。 有时上传上去3张图,结果只显示2张图, 最后一张图显示不出来的, 可能就是因为服务器推断格式时推断错误。
2. 对于上面的视频文件, 这里使用的是ALAsset类型, 这个是通过
CTAssetsPickerController来选择手机相册中的视频文件的。
然后通过生成一个视频文件名及地址, 并通过一个写方法, 写到该路径下, 写文件如下。
- (BOOL) exportDataToURL: (NSURL*) fileURL error: (NSError**) error
{
[[NSFileManager defaultManager] createFileAtPath:[fileURL path] contents:nil attributes:nil];
NSFileHandle *handle = [NSFileHandle fileHandleForWritingToURL:fileURL error:error];
if (!handle) {
return NO;
}
ALAssetRepresentation *rep = [self defaultRepresentation];
uint8_t *buffer = calloc(BufferSize,sizeof(*buffer));
NSUInteger offset = 0, bytesRead = 0;
do {
@try {
bytesRead = [rep getBytes:buffer fromOffset:offset length:BufferSize error:error];
[handle writeData:[NSData dataWithBytesNoCopy:buffer length:bytesRead freeWhenDone:NO]];
offset += bytesRead;
}@catch (NSException *exception) {
free(buffer);
return NO;
}
}while (bytesRead > 0);
free(buffer);
return YES;
}
把视频写入后,再通过NSData来取出这个视频的数据。 并添加到这个AFHttpRequestOperation的Body中, 进行传输。
(估计这里可能有更好的办法来实现这个功能, 因为上面这个写入文件后,再转成NSData感觉有些繁琐,因为我曾尝试过其它方法,如通过ALAsset来获取到这个视频文件的url地址, 然后再通过NSData直接取这个地址,结果发现上传给后台后, 后台并不能识别到这个视频文件,后台能知道确实收到了视频数据,但可能某些原因,使得前端再次去获取该视频文件时,发现播放不了。具体原因可以再次去进行研究。
尝试过程如下:
A:
上传后, 后台仅获取到文本
ALAssetRepresentation *rep = [asset defaultRepresentation];
Byte *buffer = (Byte*)malloc(rep.size);
NSUInteger buffered = [rep getBytes:buffer fromOffset:0.0 length:rep.size error:nil];
NSData *videoData = [NSData dataWithBytesNoCopy:buffer length:buffered freeWhenDone:YES];
// [formData appendPartWithFormData:videoData name:@"video1"];
[formData appendPartWithFileData:videoData name:@"video1"fileName:@"video1.mov" mimeType:@"video/quicktime"];
尝试B:
通过NSURl来取到这个地址, 然后用NSData来取视频, 然后再把这个视频进行上传。
)
有兴趣的朋友可以继续研究下去。
注:上传视频时和上面的上传图片一样,需要指定这个.mov, 及video/quicktime 类型指定。 前面的方法中要进行存储到本地时, 文件名指定为%d.mov。
相关文章推荐
- 端口概念
- 删除数据库数据
- Mac终端启动tomcat的相关问题
- hrbust 2046 哈理工oj 2046 最后的题目八个字【二维树状数组】
- Mybatis 级联属性赋值
- 《跟着小吴哥学python》之 03 python语法&基本类型
- java 微信等三方登录部署到WAS服务器上报错
- 局部字体变红
- Mac上配置ios开发环境(上)
- 父页面、子页面 获取对象方法总结
- 转移数据库表数据
- 软件工程学习进度条
- oracle恢复删除的数据
- Java过滤器与SpringMVC拦截器之间的关系与区别
- Linux主流架构运维工作简单剖析
- java类方法执行顺序
- iOS开发-检测网络状态
- [bzoj1819] [JSOI]Word Query电子字典
- UVa 123 - Searching Quickly
- Actual Practice : Scalar Valued Functions in my work - 2