码迷,mamicode.com
首页 > 微信 > 详细

iOS开发——项目实战总结&类微信朋友圈发动态功能初步-图片与视频上传

时间:2015-11-23 06:16:23      阅读:413      评论:0      收藏:0      [点我收藏+]

标签:

类微信朋友圈发动态功能初步-图片与视频上传

 

 

最近在做一个新的项目,涉及到了关于图片和视频上传和显示的功能,研究了一段时间,总结一下。

使用AFNetworking上传图片(可一次上传多张图片,包含不同类型png, jpeg)和视频

 1     AFHTTPRequestOperationManager *manager = [AFHTTPRequestOperationManager manager];
 2 
 3     AFHTTPRequestOperation *operation = [manager POST:mutPath
 4 
 5                                            parameters:param
 6 
 7                             constructingBodyWithBlock:^(id<AFMultipartFormData> formData) {
 8 
 9                                 
10 
11                                 if (mediaDatas.count > 0) {
12 
13                                     NSObject *firstObj = [mediaDatas objectAtIndexSafe:0];
14 
15                                     if ([firstObj isKindOfClass:[UIImage class]]) {     // 图片
16 
17                                         for(NSInteger i=0; i<mediaDatas.count; i++) {
18 
19                                             UIImage *eachImg = [mediaDatas objectAtIndexSafe:i];
20 
21                                             //NSData *eachImgData = UIImagePNGRepresentation(eachImg);
22 
23                                             NSData *eachImgData = UIImageJPEGRepresentation(eachImg, 0.5);
24 
25                                             [formData appendPartWithFileData:eachImgData name:[NSString stringWithFormat:@"img%d", i+1] fileName:[NSString stringWithFormat:@"img%d.jpg", i+1] mimeType:@"image/jpeg"];
26 
27                                         }
28 
29                                     }else {         // 视频
30 
31                                         ALAsset *asset = [mediaDatas objectAtIndexSafe:0];
32 
33                                         NBLog(@"asset=%@, representation=%@, url=%@", asset, [asset defaultRepresentation], [asset defaultRepresentation].url);
34 
35                                         if (asset != nil) {
36 
37                                                 NSString *videoPath = [NSDocumentsPath stringByAppendingPathComponent:[NSString stringWithFormat:@"%d.mov", 0]];    // 这里直接强制写一个即可,之前计划是用i++来区分不明视频
38 
39                                                 NSURL *url = [NSURL fileURLWithPath:videoPath];
40 
41                                                 NSError *theErro = nil;
42 
43                                                 BOOL exportResult = [asset exportDataToURL:url error:&theErro];
44 
45                                                 NBLog(@"exportResult=%@", exportResult?@"YES":@"NO");
46 
47                                                 
48 
49                                             NSData *videoData = [NSData dataWithContentsOfURL:url];
50 
51                                                 [formData appendPartWithFileData:videoData name:@"video1" fileName:@"video1.mov" mimeType:@"video/quicktime"];
52 
53                                             NBLog(@"method 2");
54 
55                                         }
56 
57                                     }
58 
59                                 }
60 
61                             } success:^(AFHTTPRequestOperation *operation, id responseObject) {
62 
63                                 NSDictionary *returnedDic = [XXBaseViewController parseResponseObj:responseObject];
64 
65  
66 
67                                 NBLog(@"post Big success returnedDic=%@", returnedDic);
68 
69                             } failure:^(AFHTTPRequestOperation *operation, NSError *error) {
70 
71                                 NBLog(@"post big file fail error=%@", error);
72 
73                                 if (errorBlock) {
74 
75                                     errorBlock(@{@"errorcode":@(error.code), @"errordomain":error.domain});
76 
77                                 }
78 
79                             }];
80 
81     
82 
83     [operation setUploadProgressBlock:^(NSUInteger bytesWritten, long long totalBytesWritten, long long totalBytesExpectedToWrite) {
84 
85         NSLog(@"bytesWritten=%d, totalBytesWritten=%lld, totalBytesExpectedToWrite=%lld", bytesWritten, totalBytesWritten, totalBytesExpectedToWrite);
86 
87         if (xxProgressView != nil) {
88 
89             [xxProgressView setProgressViewTo:totalBytesWritten*1.0/totalBytesExpectedToWrite];
90 
91         }
92 
93     }];

 

1. 注意上面上传图片时时, 需要先转为NSData, 然后再执行

1 [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来选择手机相册中的视频文件的。

然后通过生成一个视频文件名及地址, 并通过一个写方法, 写到该路径下, 写文件如下。

 

 1 - (BOOL) exportDataToURL: (NSURL*) fileURL error: (NSError**) error
 2 
 3 {
 4 
 5     [[NSFileManager defaultManager] createFileAtPath:[fileURL path] contents:nil attributes:nil];
 6 
 7     NSFileHandle *handle = [NSFileHandle fileHandleForWritingToURL:fileURL error:error];
 8 
 9     if (!handle) {
10 
11         return NO;
12 
13     }
14 
15     
16 
17     ALAssetRepresentation *rep = [self defaultRepresentation];
18 
19     uint8_t *buffer = calloc(BufferSize, sizeof(*buffer));
20 
21     NSUInteger offset = 0, bytesRead = 0;
22 
23     
24 
25     do {
26 
27         @try {
28 
29             bytesRead = [rep getBytes:buffer fromOffset:offset length:BufferSize error:error];
30 
31             [handle writeData:[NSData dataWithBytesNoCopy:buffer length:bytesRead freeWhenDone:NO]];
32 
33             offset += bytesRead;
34 
35         } @catch (NSException *exception) {
36 
37             free(buffer);
38 
39             return NO;
40 
41         }
42 
43     } while (bytesRead > 0);
44 
45     
46 
47     free(buffer);
48 
49     return YES;
50 
51 }

 

 

把视频写入后,再通过NSData来取出这个视频的数据。 并添加到这个AFHttpRequestOperation的Body中, 进行传输。

 

(估计这里可能有更好的办法来实现这个功能, 因为上面这个写入文件后,再转成NSData感觉有些繁琐,因为我曾尝试过其它方法,如通过ALAsset来获取到这个视频文件的url地址, 然后再通过NSData直接取这个地址,结果发现上传给后台后, 后台并不能识别到这个视频文件,后台能知道确实收到了视频数据,但可能某些原因,使得前端再次去获取该视频文件时,发现播放不了。具体原因可以再次去进行研究。

尝试过程如下:

A:

 

上传后, 后台仅获取到文本

                                       

 1          ALAssetRepresentation *rep = [asset defaultRepresentation];
 2 
 3                                                 Byte *buffer = (Byte*)malloc(rep.size);
 4 
 5                                                 NSUInteger buffered = [rep getBytes:buffer fromOffset:0.0 length:rep.size error:nil];
 6 
 7                                                 NSData *videoData = [NSData dataWithBytesNoCopy:buffer length:buffered freeWhenDone:YES];
 8 
 9                                                 //                                        [formData appendPartWithFormData:videoData name:@"video1"];
10 
11                                                 [formData appendPartWithFileData:videoData name:@"video1" fileName:@"video1.mov" mimeType:@"video/quicktime"];

 

尝试B:

通过NSURl来取到这个地址, 然后用NSData来取视频, 然后再把这个视频进行上传。

有兴趣的朋友可以继续研究下去。 

注:上传视频时和上面的上传图片一样,需要指定这个.mov, 及video/quicktime 类型指定。 前面的方法中要进行存储到本地时, 文件名指定为%d.mov。

iOS开发——项目实战总结&类微信朋友圈发动态功能初步-图片与视频上传

标签:

原文地址:http://www.cnblogs.com/iCocos/p/4987293.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!