系统相册的多选与单选封装(基于 AssetsLibrary)

1,198 阅读3分钟
原文链接: blog.csdn.net

在实现封装之前,首先需要了解一下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
ALAssetsGroupAlbum
ALAssetsGroupFaces
ALAssetsGroupSavedPhotos
ALAssetsGroupPhotoStream
ALAssetsGroupAll

常用的方法有:
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 
#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  *groups;/**< 存放所有照片组的数组对象 */

@property (strong, nonatomic) NSMutableArray  * 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]);
    }];
}





#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 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;

    
    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 *);

#pragma mark - **************** XFPhotoManager回调
typedef void(^ALAssetGroupBlock)(NSArray  *groups);
typedef void(^ALAssetPhotoBlock)(NSArray  * photos);
typedef void(^ALAssetFailBlock)(NSString * error);

#pragma mark - XFPhotoCollectionViewCell
typedef void(^XFPhotoCollectionViewBlock)(void);

#endif /* XFEnumConfig_h */

进行封装完这些之后就是将获得的相册列表新建一个tableviewController放进,新建一个collectionViewController存放相片,在collectionViewController中进行单选多选。具体代码不在详细在这里写。

demo地址:download.csdn.net/detail/qq_3…

以上如有错误,请留言指出,谢谢!