照片框架ALAssetsLibrary

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,即遍历相片或视频完毕,可以展示资源列表
}
}];

参考文章

ALAsset,ALAssetsLibrary,ALAssetsgroup常见属性及用法

iOS 开发之照片框架详解

iOS的AssetsLibrary框架访问所有相片