在实现封装之前,首先需要了解一下AssetsLibrary的框架(目前苹果提供了新的一个photoKit框架替代了这个框架,不过还可以用)。
AssetsLibrary框架是用iOS提供来读取和操作本地相册的,连接了我们应用程序和相册之间的访问, 该框架提供了6个类:ALAssetsLibrary,AssetsLibrary,ALAssetsGroup,ALAsset,ALAssetsFilter,ALAssetRepresentation。
AssetsLibrary: 代表整个设备中的资源库(照片库),通过 AssetsLibrary 可以获取和包括设备中的照片和视频
ALAssetsGroup: 映射照片库中的一个相册,通过 ALAssetsGroup 可以获取某个相册的信息,相册下的资源,同时也可以对某个相册添加资源。
ALAsset: 映射照片库中的一个照片或视频,通过 ALAsset 可以获取某个照片或视频的详细信息,或者保存照片和视频。
ALAssetRepresentation: ALAssetRepresentation 是对 ALAsset 的封装(但不是其子类),可以更方便地获取 ALAsset 中的资源信息,每个 ALAsset 都有至少有一个 ALAssetRepresentation 对象,可以通过 defaultRepresentation 获取。而例如使用系统相机应用拍摄的 RAW + JPEG 照片,则会有两个 ALAssetRepresentation,一个封装了照片的 RAW 信息,另一个则封装了照片的 JPEG 信息
ALASSetsGroupType: 类型:
ALAssetsGroupLibrary//从iTunes来的相册内容(如本身自带的向日葵照片)。
ALAssetsGroupAlbum//设备自身产生或从iTunes同步来的照片,但是不包括照片流跟分享流中的照片。(例如从各个软件中保存下来的图片)ALAssetsGroupEvent相机接口事件产生的相册
ALAssetsGroupFaces//脸部相册(具体不清楚)
ALAssetsGroupSavedPhotos//相机胶卷照片
ALAssetsGroupPhotoStream//照片流
ALAssetsGroupAll//除了ALAssetsGroupLibrary上面所的内容
常用的方法有:
ALAssetsLibrary
1、获取相册的组别,在这个方法的enumerationBlock中读取分组列表,包括它的名称、封面图片等等。
- (void)enumerateGroupsWithTypes:(ALAssetsGroupType)types usingBlock:(ALAssetsLibraryGroupsEnumerationResultsBlock)enumerationBlock failureBlock:(ALAssetsLibraryAccessFailureBlock)failureBlock
2、 返回一个ALAsset对象
- (void)assetForURL:(NSURL *)assetURL resultBlock:(ALAssetsLibraryAssetForURLResultBlock)resultBlock failureBlock:(ALAssetsLibraryAccessFailureBlock)failureBlock
3、返回一个ALAssetsGroup对象
- (void)groupForURL:(NSURL *)groupURL resultBlock:(ALAssetsLibraryGroupResultBlock)resultBlock failureBlock:(ALAssetsLibraryAccessFailureBlock)failureBlock
ALAssetsGroup
ALAssetsGroup就是相册组的类,可以通过这个类提供的方法来获取相册组的各种信息。
1、 获得 名称,类型,ID,NSURL
- (id)valueForProperty:(NSString *)property;
property可以是:
ALAssetsGroupPropertyName(名称)
ALAssetsGroupPropertyType(类型)
ALAssetsGroupPropertyPersistentID(ID)
ALAssetsGroupPropertyURL (NSURL)
2、 获得相册分组的封面图片
- (CGImageRef)posterImage;
3、 过滤器
- (void)setAssetsFilter:(ALAssetsFilter *)filter
ALAssetsFilter中有这些方法,是过滤类型
// Get all photos assets in the assets group.
+ (ALAssetsFilter *)allPhotos;
// Get all video assets in the assets group.
+ (ALAssetsFilter *)allVideos;
// Get all assets in the group.
+ (ALAssetsFilter *)allAssets;
4、 获得相册的组的数量
- (NSInteger)numberOfAssets;
5、 通过相册组获取里面的图片
- (void)enumerateAssetsUsingBlock:(ALAssetsGroupEnumerationResultsBlock)enumerationBlock NS_DEPRECATED_IOS(4_0, 9_0, "Use the PHFetchResult returned by fetchAssetsInAssetCollection:options: on PHAsset to enumerate the assets in an asset collection from the Photos framework instead");
- (void)enumerateAssetsWithOptions:(NSEnumerationOptions)options usingBlock:(ALAssetsGroupEnumerationResultsBlock)enumerationBlock NS_DEPRECATED_IOS(4_0, 9_0, "Use the PHFetchResult returned by fetchAssetsInAssetCollection:options: on PHAsset to enumerate the assets in an asset collection from the Photos framework instead");
- (void)enumerateAssetsAtIndexes:(NSIndexSet *)indexSet options:(NSEnumerationOptions)options usingBlock:(ALAssetsGroupEnumerationResultsBlock)enumerationBlock NS_DEPRECATED_IOS(4_0, 9_0, "Use the PHFetchResult returned by fetchAssetsInAssetCollection:options: on PHAsset to enumerate the assets in an asset collection from the Photos framework instead");
6、 增加图片
- (BOOL)addAsset:(ALAsset *)asset NS_DEPRECATED_IOS(5_0, 9_0, "Use addAssets: on a PHAssetCollectionChangeRequest: created from a PHAssetCollection in the Photos framework instead");
以上是AssetsLibrary框架的一个简单的说明。下面进行封装做一个demo。效果如下:
首先新建一个项目,导入AssetsLibrary.framework
框架。然后新建一个manager类和一个config的头文件。
代码如下:
XFPhotoManager.h:
/**
* 此类用来管理照片
*
* by sheffi 2016/07/26
*/
#import <Foundation/Foundation.h>
#import "XFEnumConfig.h"
@interface XFPhotoManager : NSObject
/**
* 单例方法
*
* @return XFPhotoManager单例方法
*/
+(instancetype)ShareInstance;
/**
* 读取相册的所有数组
*
* @param groupBlock 获取相册组成功的回调
* @param failBlock 失败的回调
*/
-(void)readAllPhotoGroups:(ALAssetGroupBlock)groupBlock andFail:(ALAssetFailBlock)failBlock;
/**
* 打开图片组
*
* @param assetsGroup 需要打开的图片组
* @param successBlock 成功的回调
* @param failBlock 失败的回调
*/
- (void)openPhotosGroup:(ALAssetsGroup *)assetsGroup Success:(ALAssetPhotoBlock)successBlock Fail:(ALAssetFailBlock)failBlock;
@end
XFPhotoManager.m中实现:
#import "XFPhotoManager.h"
@interface XFPhotoManager ()
@property (strong, nonatomic) ALAssetsLibrary *library;
@property (strong, nonatomic) ALAssetGroupBlock block;
@property (strong, nonatomic) NSMutableArray <ALAssetsGroup *> *groups;/**< 存放所有照片组的数组对象 */
@property (strong, nonatomic) NSMutableArray <ALAsset *> * photos;/**< 存放所有照片的数组对象 */
@end
@implementation XFPhotoManager
-(instancetype)init{
if (self = [super init]) {
//实例化库对象
self.library = [[ALAssetsLibrary alloc]init];
//初始化数组
self.groups = [[NSMutableArray alloc]init];
self.photos = [NSMutableArray array];
}
return self;
}
+(instancetype)ShareInstance{
static XFPhotoManager *manager = nil;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
manager = [[XFPhotoManager alloc]init];
});
return manager;
}
/**
* 创建组名叫做title的相片组
*
* @param title 组名
*/
-(void)createGroupWithTitle:(NSString *)title{
//开始创建
[self.library addAssetsGroupAlbumWithName:title resultBlock:^(ALAssetsGroup *group) {
NSLog(@"创建成功");
} failureBlock:^(NSError *error) {
NSLog(@"error = %@",[error localizedDescription]);
}];
}
/*
ALAssetsGroupLibrary //从iTunes 来的相册内容(如本身自带的向日葵照片)
ALAssetsGroupAlbum //设备自身产生或从iTunes同步来的照片,但是不包括照片流跟分享流中的照片。(例如从各个软件中保存下来的图片)
ALAssetsGroupEvent //相机接口事件产生的相册
ALAssetsGroupFaces //脸部相册
ALAssetsGroupSavedPhotos //"相册胶卷"里面的照片
ALAssetsGroupPhotoStream //照片流
ALAssetsGroupAll //除了ALAssetsGroupLibrary上面所的内容
*/
#pragma mark - **************** 读取相册的所有组
/**
* 读取相册的所有组
*
* @param groupBlock 获取组成功回调
* @param failBlock 失败回调
*/
-(void)readAllPhotoGroups:(ALAssetGroupBlock)groupBlock andFail:(ALAssetFailBlock)failBlock{
[self readAllPhotoGroups:groupBlock andFail:failBlock CameraRollHandel:^{
}];
}
/**
* 读取相册的所有组
*
* @param groupBlock 获取组成功回调
* @param failBlock 失败的回调
* @param cameraRollHandle 相机胶卷不为nil的时候的回调
*/
-(void)readAllPhotoGroups:(ALAssetGroupBlock)groupBlock andFail:(ALAssetFailBlock)failBlock CameraRollHandel:(void (^)(void))cameraRollHandle{
//删除之前的组
[self.groups removeAllObjects];
__block __weak typeof(self) copy_self = self;
//开始遍历
[self.library enumerateGroupsWithTypes:ALAssetsGroupAll usingBlock:^(ALAssetsGroup *group, BOOL *stop) {
//如果返回的组存在
if (group) {
//对group进行过滤,只要照片
[group setAssetsFilter:[ALAssetsFilter allPhotos]];
//添加数据
[copy_self.groups addObject:group];
//进行顺序判断
if ([self containCamerRoll:group] == true) {
//删除当前位置的数组
[self.groups removeObjectAtIndex:self.groups.count - 1];
[self.groups insertObject:group atIndex:0];
}
//回调数据
groupBlock([NSArray arrayWithArray:copy_self.groups]);
//进行序列后的回调
if ([self containCamerRoll:group] == true) {
cameraRollHandle();
}
}
} failureBlock:^(NSError *error) {
//失败回调
failBlock(error.localizedDescription);
}];
}
/**
* 判断是否包含相机胶卷
*
* @param group ALAssetsGroup对象
*
* @return true表示包含,false不包含
*/
-(BOOL)containCamerRoll:(ALAssetsGroup *)group{
//如果是相机胶卷,放到第一位,这里只适配英文以及中文
NSString *nameCN = NSLocalizedString([group valueForProperty:ALAssetsGroupPropertyName], @"");
NSString * nameEN = NSLocalizedString([group valueForProperty:ALAssetsGroupPropertyName], @"");
//对当前数组进行排序
if ([nameCN isEqualToString:@"相机胶卷"] || [nameEN isEqualToString: @"Camera Roll"]) {
return true;
}
return false;
}
#pragma mark - **************** 打开图片组
-(void)openPhotosGroup:(ALAssetsGroup *)assetsGroup Success:(ALAssetPhotoBlock)successBlock Fail:(ALAssetFailBlock)failBlock{
//删除所有的照片对象
[self.photos removeAllObjects];
__block __weak typeof(self) copy_self = self;
//获取当前组的url数据
NSURL * url = [assetsGroup valueForProperty:ALAssetsGroupPropertyURL];
//打开当前的组
[self.library groupForURL:url resultBlock:^(ALAssetsGroup *group) {
[copy_self photosInGroups:group Block:successBlock];
} failureBlock:^(NSError *error) {
//失败的回调
failBlock(error.localizedDescription);
}];
}
//获取所有的照片对象
- (void)photosInGroups:(ALAssetsGroup *)group Block:(ALAssetPhotoBlock)photoBlock{
//开始读取
[group enumerateAssetsUsingBlock:^(ALAsset *result, NSUInteger index, BOOL *stop) {
//如果不为空或者媒体为图片
if (result != nil && [[result valueForProperty:ALAssetPropertyType] isEqualToString:ALAssetTypePhoto]) {
//添加数据
[self.photos addObject:result];
//数目达标后统一进行回调
if (index == group.numberOfAssets - 1) {
//回调
photoBlock([NSArray arrayWithArray:self.photos]);
}
}
}];
}
@end
XFEnumConfig中:
#ifndef XFEnumConfig_h
#define XFEnumConfig_h
@import UIKit;
@import AssetsLibrary;
@import Photos;
typedef enum : NSUInteger {
XFChoosePhotoSequenceTypeDefault = 0,//默认是按照选择的顺序
XFChoosePhotoSequenceTypeData, //按照图片在相册的顺序
} XFChoosePhotoSequenceType;
#pragma mark - **************** 照片选择的Block回调
typedef void(^ImageBlock)(NSArray<UIImage *> *);
#pragma mark - **************** XFPhotoManager回调
typedef void(^ALAssetGroupBlock)(NSArray <ALAssetsGroup *> *groups);
typedef void(^ALAssetPhotoBlock)(NSArray <ALAsset *> * photos);
typedef void(^ALAssetFailBlock)(NSString * error);
#pragma mark - XFPhotoCollectionViewCell
typedef void(^XFPhotoCollectionViewBlock)(void);
#endif /* XFEnumConfig_h */
进行封装完这些之后就是将获得的相册列表新建一个tableviewController放进,新建一个collectionViewController存放相片,在collectionViewController中进行单选多选。具体代码不在详细在这里写。
demo地址:http://download.youkuaiyun.com/detail/qq_34195670/9588418
以上如有错误,请留言指出,谢谢!