公司产品做了备份相关功能,主要是检测未备份的图片,上传。以及检测已备份却不在相册的图片,恢复。
功能实现起来也不是很难,比对的话我用的MD5 ,进行比对文件是否重复,是否已上传 ,或未上传。MD5反正算是个问题,解决的办法不是很好,我会改进,因为功能急,暂时没有好的办法,只能 这么来了。具体怎么回事,我和大家说道说道。
获取系统相册的图片,在iOS8之前,一直使用的是
那么其二,就是枚举便利整个资源库,找出组。方法如下。
if (isAutoBackupOfVideo||isAutoBackupOfPhoto) { if (!self.assetsLibrarry) { self.assetsLibrarry=[[ALAssetsLibrary alloc]init]; } dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ NSMutableArray *groups=[NSMutableArray array]; [self.assetsLibrarry enumerateGroupsWithTypes:ALAssetsGroupSavedPhotos usingBlock:^(ALAssetsGroup *group, BOOL *stop) { if (group) { [groups addObject:group]; }else{ for (ALAssetsGroup *singeGroup in groups) { NSString *albumName=[singeGroup valueForProperty:ALAssetsGroupPropertyName]; NSMutableArray *photos=[NSMutableArray array]; NSMutableArray *videos=[NSMutableArray array]; dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ [singeGroup enumerateAssetsUsingBlock:^(ALAsset *result, NSUInteger index, BOOL *stop) { if (result) { if (IsEquallString(ALAssetTypePhoto, [result valueForProperty:ALAssetPropertyType])) { if (isAutoBackupOfPhoto) { Photo *photo=[[Photo alloc]init]; photo.url=[[[result defaultRepresentation] url] absoluteString]; photo.album=albumName; photo.thumbnail=[UIImage imageWithCGImage:[result thumbnail]]; photo.name=[[result defaultRepresentation] filename]; photo.type=[photo.name pathExtension]; photo.size=[NSString stringWithFormat:@"%lld",[[result defaultRepresentation] size]]; [photos addObject:result]; } } if (IsEquallString(ALAssetTypeVideo, [result valueForProperty:ALAssetPropertyType])) { if (isAutoBackupOfVideo) { Video *video=[[Video alloc]init]; video.url=[[[result defaultRepresentation] url] absoluteString]; video.album=albumName; video.name=[[result defaultRepresentation] filename]; video.type=[video.name pathExtension]; video.thumbnail=[UIImage imageWithCGImage:[result thumbnail]]; video.size=[NSString stringWithFormat:@"%lld",[[result defaultRepresentation] size]]; [videos addObject:result]; } } }else{ dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ if (photos.count) { [self uploadPhoto:photos]; } if (videos.count) { [self uploadVideos:videos]; } }); } }]; }); } } } failureBlock:^(NSError *error) { }]; }); }
你可以看见,资源库给你的是asset 对象,对象中有照片,也有视频。所以我们做了判断。判断依据就是ALAssetType。这里面有一个坑,在枚举方法的参数上。
enumerateGroupsWithTypes:ALAssetsGroupSavedPhotos usingBlock:^(ALAssetsGroup *group, BOOL *stop){}WithTypes:(这个参数传递你想拿到的照片组类型)
enum { ALAssetsGroupLibrary NS_ENUM_DEPRECATED_IOS(4_0, 9_0) = (1 <<0), // The Library group that includes all assets. ALAssetsGroupAlbum NS_ENUM_DEPRECATED_IOS(4_0, 9_0) = (1 <<1), // All the albums synced from iTunes or created on the device. ALAssetsGroupEvent NS_ENUM_DEPRECATED_IOS(4_0, 9_0) = (1 <<2), // All the events synced from iTunes. ALAssetsGroupFaces NS_ENUM_DEPRECATED_IOS(4_0, 9_0) = (1 <<3), // All the faces albums synced from iTunes. ALAssetsGroupSavedPhotos NS_ENUM_DEPRECATED_IOS(4_0, 9_0) = (1 <<4), // The Saved Photos album. #if __IPHONE_5_0 <= __IPHONE_OS_VERSION_MAX_ALLOWED ALAssetsGroupPhotoStream NS_ENUM_DEPRECATED_IOS(5_0, 9_0) = (1 <<5), // The PhotoStream album. #endif ALAssetsGroupAll NS_ENUM_DEPRECATED_IOS(4_0, 9_0) = 0xFFFFFFFF, // The same as ORing together all the available group types, };
ALAssetsGroupAll实际则不是,为什么呢,主要是照片流。照片流这个组的对象很奇怪,data是空得。我想想也是。照片流本身就是一个映射类似的存在。
还有就是。既然是对象,我们怎么算MD5值呢?
本以为直接读取二进制,data,算出MD5。但是结果算出来的值居然和文件本身的值不一样。没有深究为什么不一样,直接换了一种解决办法。直接把对象的image写入文件,计算文件的MD5,呵呵,对了。奇怪。
但是计算MD5其实不是一个很好的办法。为什么呢。因为速度慢啊。。。解决办法。想了一下。准备采取多值对比。(如:时间,名称),这样速度就会大幅度提升。
/*****************************************************分割线***********************************************/
下面讲讲另外一个值得注意的地方。那就是生命周期的问题。一个ALAssetsLibrary只在它自身的生命周期内有效。超出生命周期,那就导致你取不出来图片。简单来说,在一个ALAssetsLibrary的生命没有结束的时候,不要重新创建一个ALAssetsLibrary,这会结束上一个ALAssetsLibrary,导致文件提取不出来。
下面是,读取相册图片的MD5,及写入相册的源码。有需要的参考。
//获得本地图片的MD5数组 -(void)getLocalPhotos:(getLocalPhotosSuccessBlock)block{ if (!self.assetsLibrarry) { self.assetsLibrarry=[[ALAssetsLibrary alloc]init]; } NSMutableArray *groups=[NSMutableArray array]; [self.assetsLibrarry enumerateGroupsWithTypes:ALAssetsGroupSavedPhotos usingBlock:^(ALAssetsGroup *group, BOOL *stop) { if (group) { [groups addObject:group]; }else{ // for (ALAssetsGroup *singeGroup in groups) { NSString *albumName=[singeGroup valueForProperty:ALAssetsGroupPropertyName]; NSMutableArray *photos=[NSMutableArray array];//存储ALAsset对象 NSMutableArray * photoArr = [NSMutableArray array];//存储photo对象 dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ [singeGroup enumerateAssetsUsingBlock:^(ALAsset *result, NSUInteger index, BOOL *stop) { if (result) { if (IsEquallString(ALAssetTypePhoto, [result valueForProperty:ALAssetPropertyType])) { Photo *photo=[[Photo alloc]init]; photo.url=[[[result defaultRepresentation] url] absoluteString]; photo.album=albumName; photo.thumbnail=[UIImage imageWithCGImage:[result thumbnail]]; photo.name=[[result defaultRepresentation] filename]; photo.type=[photo.name pathExtension]; photo.md5 =[self getImageMD5WithUrl:result]; NSDate * date = [result valueForProperty:ALAssetPropertyDate]; NSDateFormatter *dateformatter=[[NSDateFormatter alloc] init]; dateformatter.dateFormat=@"YYYY-MM-dd HH:mm:ss"; photo.lastWriteTime = [dateformatter stringFromDate:date]; photo.size=[NSString stringWithFormat:@"%lld",[[result defaultRepresentation] size]]; photo.result = result; [photos addObject:result]; [photoArr addObject:photo]; } }else{ dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ if (photoArr.count) { block(photoArr); } }); } }]; }); } // } } failureBlock:^(NSError *error) { }]; } //写入相册 -(void)storeFinishByTypeFile:(TypeFile*)typeFile andIsSuccess:(BOOL)isSuccess{ if (isSuccess) { NSString *path=[self getFilePathWithFile:typeFile]; NSData *imageData=[NSData dataWithContentsOfFile:path]; UIImage *image=[UIImage imageWithData:imageData]; if (!self.assetsLibrarry) { self.assetsLibrarry = [[ALAssetsLibrary alloc]init]; } [self.assetsLibrarry writeImageToSavedPhotosAlbum:image.CGImage orientation:(ALAssetOrientation)image.imageOrientation completionBlock:^(NSURL* assetURL, NSError* error) { if (error!=nil) { [Utils showAlertViewByText:[NSString stringWithFormat:@"%@保存失败",typeFile.name]]; }else{ typeFile.url=[assetURL description]; NSLog(@"Success--%@",typeFile.url); [[NSFileManager defaultManager] removeItemAtPath:path error:nil]; } }]; }else{ [Utils showAlertViewByText:[NSString stringWithFormat:@"%@保存失败",typeFile.name]]; } }
for (ALAsset *asset in photos) { NSString * MD5Str = [self getImageMD5WithUrl:asset ]; if (MD5Str.length>0) { [[RequestIP shardRequestIP].localMd5Arr addObject:MD5Str]; if([MD5Arr indexOfObject:MD5Str]== NSNotFound){ NSLog(@"NSNotFound!"); if ([uploadArr indexOfObject:MD5Str] == NSNotFound) { [uploadArr addObject:MD5Str]; NSLog(@"MD5Str:%@",MD5Str); if (!IS_AUTO_CopyPhotos) { break; }