iOS 相册备份功能实现
公司产品做了备份相关功能,主要是检测未备份的图片,上传。以及检测已备份却不在相册的图片,恢复。
功能实现起来也不是很难,比对的话我用的MD5 ,进行比对文件是否重复,是否已上传 ,或未上传。MD5反正算是个问题,解决的办法不是很好,我会改进,因为功能急,暂时没有好的办法,只能 这么来了。具体怎么回事,我和大家说道说道。
获取系统相册的图片,在iOS8之前,一直使用的是<AssetsLibrary/AssetsLibrary.h>,但是iOS8 之后,苹果给我们提供了新的好用的photos framework。由于写的时候,没有研究过这个框架。所以还是使用的<AssetsLibrary/AssetsLibrary.h>。这是之一。
那么其二,就是枚举便利整个资源库,找出组。方法如下。
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_ALLOWEDALAssetsGroupPhotoStream NS_ENUM_DEPRECATED_IOS(5_0, 9_0) = (1 << 5), // The PhotoStream album.
#endifALAssetsGroupAll 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;}
大概 也就这么多。详细的源码,我就不发出来了。有不懂得可以咨询我。
iOS 相册备份功能实现相关推荐
- iOS 通讯录备份、恢复
和相册 备份一样,公司产品备份功能有通讯录备份 功能,自然也有通讯录恢复了.iOS通讯录相关操作,iOS对通讯录的操作离不开的框架: #import <AddressBook/A ...
- iOS相册、拍照、iCloud使用
使用系统相册.拍照.iCloud功能 1.添加权限: 相机权限 Privacy - Camera Usage Description App想要访问您手机的系统相机,是否允许? 相册权限 Privac ...
- HTML精仿ios相册,高仿ios相册地图功能
本篇文章已授权微信公众号 guolin_blog (郭霖) 独家发布 老规矩先上图, 高仿 ios 相册, 地图算法分析. 下载.gif 百度地图 SDK 新增点聚合功能.通过该功能,可通过缩小地图层 ...
- android 快盘接口,金山快盘Android版自动备份功能详解
近日,金山快盘Android版发布了新版本--1.9.3版,在这一版本中,小编发现了几大功能上的亮点,诸如密码锁功能.增加了常见问题答疑.优化"问题反馈"功能等,但是,新版手机快盘 ...
- Tenorshare UltData for Mac(iOS数据恢复备份软件)
不小心删除了重要数据无法恢复怎么办?Tenorshare UltData for mac版是一个MacOS上的iOS数据恢复备份软件,可以帮助你轻松的找回手机里原有的数据,照片,短信,通话记录,联系人 ...
- 苹果自带相册打马赛克_用于手机相册备份的照片备份哪个软件好?
在研究照片备份哪个软件好的时候,非常需要注意的一点是,同品牌的手机照片数据迁移就还好,一般主流智能手机同品牌都有自带数据和文件迁移功能,但跨品牌的手机就需要用到相册备份软件,考虑到换机的不便,今天就来 ...
- iOS钥匙串三种提取方案【iOS加密备份】【keychain_dumper】【frida-objection】
iOS钥匙串(keychain)是iOS操作系统提供的一种安全存储机制,用于存储用户的敏感信息(如密码等).钥匙串管理器可以在任何应用和扩展中安全地存储和访问用户的敏感信息,而不会被其他应用的访问或破 ...
- android照片备份软件下载,加密相册备份app下载
加密相册备份app是一款相册文件加密的安全防护软件.加密相册备份app给你的照片.相册.文件上密码,保存美好回忆,不被他人窥探,操作简单,多重保护,不怕被泄露翻看,给自己的隐私多上基层保险,保护自己的 ...
- java android 相册_基于安卓Android studio相册备份及管理系统的设计
基于安卓Android studio相册备份及管理系统的设计(论文10000字,程序代码) 摘要:时代在不断地进步与发展着,用户手中的移动中终端越来越多的占据了人们的生活,可以说人们现在是十分依赖手机 ...
最新文章
- 【Qt】Qt再学习(八):Media Player(Qt实现多媒体播放器)
- 实现量子计算,我们还需要做些什么?
- linux 脚本 变量为空,Shell脚本中判断输入变量或者参数是否为空的方法
- 还想“躺着挣钱”?这家背靠世界500强的工程机械企业如何做?
- LeetCode Algorithm 129. 求根节点到叶节点数字之和
- HONGJIN4 2013
- Atitit 知识结构化的艺术 目录 1. 知识信息结构化脑图	2 1.1. 散乱化模式	2 2. 直线排列	2 2.1.1. 直排	2 2.1.2. 链表模式	2 3. 树形排列	2 3.1.
- t470换屏线_硬件笔记之Thinkpad T470P更换2K屏幕
- Unity PlayerPrefs 游戏存档
- scrapy爬虫之贝壳房产信息
- 物联网概念的理解,物联网核心要素是什么?
- c语言中浮点数取整函数,浮点取整函数
- 〖Python接口自动化测试实战篇⑦〗- 接口抓包工具 Fiddler 的使用
- DUBBO服务为null的情况
- 路由器当交换机用,应该怎样配置?
- k8s入坑之报错(4)报错:repomod.xml signature could not be verified
- 基于语料库的汉语形容词宾语与名词句法语义关系分析
- selenium调用IE浏览器
- (23)Linux基础-系统磁盘阵列raid
- 1418 -This function has none of DETERMINISTIC, NO SQL, or READS SQL DATA in its declaration