ALAssetsLibrary介绍
在iOS中,照片库并不只是照片的集合,同时也包含了视频。
在 AssetsLibrary 中两者都有相同类型的对象去描述,只是类型不同而已。
这里稍微介绍一下概念:
- AssetsLibrary: 代表整个设备中的资源库(照片库),通过 AssetsLibrary 可以获取设备中的照片和视频
- ALAssetsGroup: 映射照片库中的一个相册,通过 ALAssetsGroup 可以获取某个相册的信息,相册下的资源,同时也可以对某个相册添加资源。
- ALAsset: 映射照片库中的一个照片或视频,通过 ALAsset 可以获取某个照片或视频的详细信息,或者保存照片和视频。
- ALAssetRepresentation: ALAssetRepresentation可以更方便地获取 ALAsset 中的资源信息,每个 ALAsset 都有至少有一个 ALAssetRepresentation 对象,可以通过 defaultRepresentation 获取。
坑
注意!注意!先说说坑,否则直接上手你会和我一样悲剧的。
当然你也可以跳过去不看 : )
异步
我在开发过程中,是这样的思路:
遍历相册->遍历时添加相册到数组->遍历完成,取数组,填入照片浏览器
这样一看好像没啥错,但是由于它的异步处理,意味着“遍历时添加相册到数组”,”遍历完成,取数组填入照片浏览器“不是顺序执行。
它们将同时开始,相当于没等到添加完,就已经开始填入照片了。这样的话,数组永远都是空的。
由于整个 AssetsLibrary 中对相册、资源的获取和保存都是使用异步处理(Asynchronous),这是考虑到资源文件体积相当比较大(还可能很大)。
例如遍历相册操作,相册的结果使用 block 输出,如果相册遍历完毕,则最后一次输出的 block 中的 group 参数值为 nil。
我们可以通过判断group是否为nil来知道是否遍历完成。
AssetsLibrary实例需要强引用
在通过AsssetsLibrary,获取到照片和视频时。以为万事大吉。
但是当我把对应的asset放进照片浏览器时,却一直没有图片。
经过一番调试,发现存储asset对象的数组,里面的对象都已经为空了。
原因在于:
当我们把这些获取到的相册和资源储存到数组时,实际上只是在数组中储存了这些相册和资源在 AssetsLibrary 中的引用(指针)。
因而无论把相册和资源储存数组后如何利用这些数据,都首先需要确保 AssetsLibrary 没有被 ARC 释放。
否则把数据从数组中取出来时,会发现对应的引用数据已经丢失。这一点较为容易被忽略。
因此建议在使用 AssetsLibrary 的 viewController 中,把 AssetsLibrary 作为一个强持有的 property 或私有变量,避免在枚举出 AssetsLibrary 中所需要的数据后,AssetsLibrary 就被 ARC 释放了。
使用
获取所有相册
通过ALAssetsLibrary的实例方法,得到ALAssetsGroup类数组。
ALAssetsLibrary *assetsLibrary;
NSMutableArray *groupArray;
assetsLibrary = [[ALAssetsLibrary alloc] init];
groupArray=[[NSMutableArray alloc] initWithCapacity:1];
[assetsLibrary enumerateGroupsWithTypes:ALAssetsGroupAll usingBlock:^(ALAssetsGroup *group, BOOL *stop) {
if (group!=nil) {
[groupArray addObject:group];
// 通过这个可以知道相册的名字,从而也可以知道安装的部分应用
//例如 Name:柚子相机, Type:Album, Assets count:1
NSLog(@"%@",group);
}else{
if ([_albumsArray count] > 0) {
// 把所有的相册储存完毕,可以展示相册列表
} else {
// 没有任何有资源的相册,输出提示
}
}
} failureBlock:^(NSError *error) {
NSLog(@"Group not found!\n");
}];
获取相册下的照片
使用类型为ALAssetsGroup的group对象,获取ALAsset,来得到图片资源
[_group enumerateAssetsUsingBlock:^(ALAsset *result, NSUInteger index, BOOL *stop) {
if (result) {
NSLog(@"%@",result);
image=[UIImage imageWithCGImage: result.thumbnail];
}else{
// result 为 nil,即遍历相片或视频完毕,可以展示资源列表
}
}];
参考文章