ALAssetsLibrary学习-访问相册所有相片


ALAssetsLibrary提供了我们对iOS设备中的相片、视频的访问,而平常我们常用UIImagePickerController类来完成,但有时这个类并不能满足我们的需求,比如获取或者修改相片的exif信息等。 详情请查阅: 官方文档


!注意

ALAssetsLibrary库是iOS4之后可用的,但从最新的官方文档来看,iOS9之后这个库被废弃了,当然有些功能还是可以用的,但是官方建议使用他们提供的Photos Framework[1]

AssetsLibrary组成

  • AssetsLibrary: 代表整个设备中的资源库(照片库),通过 AssetsLibrary 可以获取和包括设备中的照片和视频;
  • ALAssetsGroup:映射照片库中的一个相册,通过 ALAssetsGroup 可以获取某个相册的信息,相册下的资源,同时也可以对某个相册添加资源;
  • ALAsset: 映射照片库中的一个照片或视频,通过 ALAsset 可以获取某个照片或视频的详细信息,或者保存照片和视频;
  • ALAssetRepresentation:ALAssetRepresentation 是对 ALAsset 的封装(但不是其子类),可以更方便地获取 ALAsset 中的资源信息,每个 ALAsset 都有至少有一个 ALAssetRepresentation 对象,可以通过 defaultRepresentation 获取。而例如使用系统相机应用拍摄的 RAW + JPEG 照片,则会有两个 ALAssetRepresentation,一个封装了照片的 RAW 信息,另一个则封装了照片的 JPEG 信息。

获取exif信息

导入库文件

使用ALAssetsLibrary需要添加AssetsLibrary.framework然后引入

#import 

ALAssetsLibrary的使用

首先创建ALAssetsLibrary实例

ALAssetsLibrary *assetsLibrary=[[ALAssetsLibrary alloc] init];

使用- enumerateGroupsWithTypes:usingBlock:failureBlock:方法调用给定的block遍历相册,从而可以通过valueForProperty:获取到asset group的相关信息,相册的名字类型存储id位置地址

  • ALAssetsGroupPropertyName:关键字对应相册名字的property
  • ALAssetsGroupPropertyType:关键字对应相册类型的property
  • ALAssetsGroupPropertyPersistentID:关键字对应相册存储id的property
  • ALAssetsGroupPropertyURL:关键字对应相册存储位置地址的property
[assetsLibrary enumerateGroupsWithTypes:ALAssetsGroupAll usingBlock:^(ALAssetsGroup *group, BOOL *stop) {
 if (group) {
 [groupArray addObject:group]; // 通过这个可以知道相册的名字,从而也可以知道安装的部分应用 
//例如 Name:美颜相机, Type:Album, Assets count:1
 NSLog(@"===>%@",group);
 NSLog(@"ALAssetsGroupPropertyName:%@",[group valueForProperty:ALAssetsGroupPropertyName]); 
} 
} 
failureBlock:^(NSError *error) {
 NSLog(@"Group not found!\n");
 }];

然后使用enumerateAssetsUsingBlock:方法遍历ALAssetsGroup,从而通过valueForProperty:可以获取到asset的相关信息:地理位置信息创建时间描述信息url路径等。

  • ALAssetPropertyLocation:对应asset的地理位置信息
  • ALAssetPropertyDuration:type为视频的话,对应视频的时长
  • ALAssetPropertyDate:对应asset的创建时间
  • ALAssetPropertyRepresentations:对应asset的描述信息
  • ALAssetPropertyAssetURL:对应asset的url路径- ......
 [group enumerateAssetsUsingBlock:^(ALAsset *result, NSUInteger index, BOOL *stop) { 
if (result) {
 [imageArray addObject:result]; 
NSLog(@"~~~~~~%@",result);
NSLog(@"ALAssetPropertyLocation:%@",[result valueForProperty:ALAssetPropertyLocation]); //如果资源是视频,查看视频的时长 
NSLog(@"ALAssetPropertyDuration:%@",[result valueForProperty:ALAssetPropertyDuration]); //查看资源的方向,图片的旋转方向
NSLog(@"ALAssetPropertyOrientation:%@",[result valueForProperty:ALAssetPropertyOrientation]); //查看资源的创建时间 
NSLog(@"ALAssetPropertyDate:%@",[result valueForProperty:ALAssetPropertyDate]); //查看资源的描述信息 
NSLog(@"ALAssetPropertyRepresentations:%@",[result valueForProperty:ALAssetPropertyRepresentations]); 
NSLog(@"ALAssetPropertyURLs:%@",[result valueForProperty:ALAssetPropertyURLs]); 
NSLog(@"ALAssetPropertyAssetURL:%@",[result valueForProperty:ALAssetPropertyAssetURL]);//查看资源的url路径  
} }];

AssetsLibrary的一些注意点:

AssetsLibrary实例需要使用强引用

当我们把这些获取到的相册和资源储存到数组时,实际上只是在数组中储存了这些相册和资源在 AssetsLibrary 中的引用(指针),因而无论把相册和资源储存数组后如何利用这些数据,都首先需要确保 AssetsLibrary 没有被 ARC 释放,否则把数据从数组中取出来时,会发现对应的引用数据已经丢失。所以,建议在使用 AssetsLibrary 的 viewController 中,把 AssetsLibrary 作为一个强持有的 property 或私有变量,避免在枚举出 AssetsLibrary 中所需要的数据后,AssetsLibrary 就被 ARC 释放了。

AssetsLibrary遵循写入优先原则

写入优先也就是說,在利用 AssetsLibrary 读取资源的过程中,有任何其它的进程(不一定是同一个 App)在保存资源时,就会收到 ALAssetsLibraryChangedNotification,让用户自行中断读取操作。

开启Photo Stream容易导致exception

本质上,这跟上面的 AssetsLibrary 遵循写入优先原则是同一个问题。如果用户开启了共享照片流(Photo Stream),共享照片流会以 mstreamd 的方式“偷偷”执行,当有人把相片写入 Camera Roll 时,它就会自动保存到 Photo Stream Album 中,如果用户刚好在读取,那就跟上面说的一样产生 exception 了。我们可以通过下面的接口在需要保护的时刻关闭监听共享照片流产生的频繁通知信息。

[ALAssetsLibrary disableSharedPhotoStreamsSupport];

扩展

除了使用ALAssetsLibrary和Photos Framework,还可以使用imageIO这个偏底层的框架来获取图片的exif信息,同时这个框架也可对exif信息进行修改。传送门

参考链接:ALAssetsLibrary获取所有图片、ALAssetsLibrary学习总结、iOS开发之照片框架详解

下一篇:PhotoKit简介


  1. 这是一个支持照片编辑扩展的框架。请查阅 Photos framework 文档。 ↩

你可能感兴趣的:(ALAssetsLibrary学习-访问相册所有相片)