自己最近抽空写了一个相册多选框架,用到对一些对相册相关的操作,使用的便是iOS8.0之后,apple推出的新框架 Photos.framework

github地址:https://github.com/longitachi/ZLPhotoBrowser 喜欢的朋友可以给个star

下载的朋友建议去git上下载,由于csdn的资源不支持实施更改,git上将持续更新

iOS photos iOS Photos 相册_Photos.framework

iOS photos iOS Photos 相册_iOS相册多选_02

iOS photos iOS Photos 相册_iOS相册多选_03

iOS photos iOS Photos 相册_Photos.framework_04

iOS photos iOS Photos 相册_浏览网络及本地图片_05


废话不多说,来干货


以下操作都需要导入<Photos/Photos.h>头文件

1.判断相册访问权限

   首先我们访问相册,肯定有需要判断是否有访问权限的时候,然后做出相应的操作

PHAuthorizationStatus status = [PHPhotoLibrary authorizationStatus];
if (status == PHAuthorizationStatusRestricted ||
    status == PHAuthorizationStatusDenied) {
    // 这里便是无访问权限
}

2.实时监听相册内部图片变化


[[PHPhotoLibrary sharedPhotoLibrary] registerChangeObserver:self];


当然,这个"self"是要遵守  PHPhotoLibraryChangeObserver 协议的



回调方法如下,不过这个地方是有一个坑的,就是这个回调是在一个子线程里面,如果你想要对UI进行操作的话,则必须回调主线程

//相册变化回调
- (void)photoLibraryDidChange:(PHChange *)changeInstance
{
    dispatch_sync(dispatch_get_main_queue(), ^{
        // your codes
    });
}



3.读取相册内所有图片资源


对相册资源的相关操作,apple多都放在了 PHAsset内


#pragma mark - 获取相册内所有照片资源
- (NSArray<PHAsset *> *)getAllAssetInPhotoAblumWithAscending:(BOOL)ascending
{
    NSMutableArray<PHAsset *> *assets = [NSMutableArray array];
    
    PHFetchOptions *option = [[PHFetchOptions alloc] init];
    //ascending 为YES时,按照照片的创建时间升序排列;为NO时,则降序排列
    option.sortDescriptors = @[[NSSortDescriptor sortDescriptorWithKey:@"creationDate" ascending:ascending]];
    
    PHFetchResult *result = [PHAsset fetchAssetsWithMediaType:PHAssetMediaTypeImage options:option];
    
    [result enumerateObjectsUsingBlock:^(id  _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {
        PHAsset *asset = (PHAsset *)obj;
        NSLog(@"照片名%@", [asset valueForKey:@"filename"]);
        [assets addObject:asset];
    }];
    
    return assets;
}




4.根据获取的PHAsset对象,解析图片


PHImageRequestOptions *option = [[PHImageRequestOptions alloc] init];
    //仅显示缩略图,不控制质量显示
    /**
     PHImageRequestOptionsResizeModeNone,
     PHImageRequestOptionsResizeModeFast, //根据传入的size,迅速加载大小相匹配(略大于或略小于)的图像
     PHImageRequestOptionsResizeModeExact //精确的加载与传入size相匹配的图像
     */
    option.resizeMode = PHImageRequestOptionsResizeModeFast;
    option.networkAccessAllowed = YES;
    //param:targetSize 即你想要的图片尺寸,若想要原尺寸则可输入PHImageManagerMaximumSize
    [[PHCachingImageManager defaultManager] requestImageForAsset:asset targetSize:size contentMode:PHImageContentModeAspectFit options:option resultHandler:^(UIImage * _Nullable image, NSDictionary * _Nullable info) {
        //解析出来的图片
    }];




5.获取所有智能相册(即默认的,如“所有照片”“屏幕快照”等)


PHFetchResult *smartAlbums = [PHAssetCollection fetchAssetCollectionsWithType:PHAssetCollectionTypeSmartAlbum subtype:PHAssetCollectionSubtypeAlbumRegular options:nil];
[smartAlbums enumerateObjectsUsingBlock:^(PHAssetCollection * _Nonnull collection, NSUInteger idx, BOOL *stop) {
    NSLog(@"相册名字:%@", collection.localizedTitle);
}];





智能相册的title不出意外都是英文,下面提供一个对应的中文名


- (NSString *)transformAblumTitle:(NSString *)title
{
    if ([title isEqualToString:@"Slo-mo"]) {
        return @"慢动作";
    } else if ([title isEqualToString:@"Recently Added"]) {
        return @"最近添加";
    } else if ([title isEqualToString:@"Favorites"]) {
        return @"最爱";
    } else if ([title isEqualToString:@"Recently Deleted"]) {
        return @"最近删除";
    } else if ([title isEqualToString:@"Videos"]) {
        return @"视频";
    } else if ([title isEqualToString:@"All Photos"]) {
        return @"所有照片";
    } else if ([title isEqualToString:@"Selfies"]) {
        return @"自拍";
    } else if ([title isEqualToString:@"Screenshots"]) {
        return @"屏幕快照";
    } else if ([title isEqualToString:@"Camera Roll"]) {
        return @"相机胶卷";
    }
    return nil;
}






Localized resources can be mixed YES
//或者右键plist文件Open As->Source Code 添加
<key>CFBundleAllowMixedLocalizations</key>
<true/>




6.获取所有用户创建的相册


PHFetchResult *userAlbums = [PHAssetCollection fetchAssetCollectionsWithType:PHAssetCollectionTypeAlbum subtype:PHAssetCollectionSubtypeSmartAlbumUserLibrary options:nil];
[userAlbums enumerateObjectsUsingBlock:^(PHAssetCollection * _Nonnull collection, NSUInteger idx, BOOL * _Nonnull stop) {
    NSLog(@"相册名字:%@", collection.localizedTitle);
}];




7.获取每个相册下的所有照片对象(PHAsset)


#pragma mark - 获取指定相册内的所有图片
- (NSArray<PHAsset *> *)getAssetsInAssetCollection:(PHAssetCollection *)assetCollection ascending:(BOOL)ascending
{
    NSMutableArray<PHAsset *> *arr = [NSMutableArray array];
    
    PHFetchResult *result = [self fetchAssetsInAssetCollection:assetCollection ascending:ascending];
    [result enumerateObjectsUsingBlock:^(id  _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {
        [arr addObject:obj];//这个obj即PHAsset对象
    }];
    return arr;
}




8.验证该图片是否在本地(若开启了iCloud照片存储,则图片会定时上传到网上,本地不存在)


PHImageRequestOptions *option = [[PHImageRequestOptions alloc] init];
    option.networkAccessAllowed = NO;
    option.synchronous = YES;
    
    __block BOOL isInLocalAblum = YES;
    
    [[PHCachingImageManager defaultManager] requestImageDataForAsset:asset options:option resultHandler:^(NSData * _Nullable imageData, NSString * _Nullable dataUTI, UIImageOrientation orientation, NSDictionary * _Nullable info) {
        isInLocalAblum = imageData ? YES : NO;
    }];
    return isInLocalAblum;




9.获取LivePhoto


PHLivePhotoRequestOptions *option = [[PHLivePhotoRequestOptions alloc] init];
    option.version = PHImageRequestOptionsVersionCurrent;
    option.deliveryMode = PHImageRequestOptionsDeliveryModeOpportunistic;
    option.networkAccessAllowed = YES;
    
    [[PHCachingImageManager defaultManager] requestLivePhotoForAsset:asset targetSize:PHImageManagerMaximumSize contentMode:PHImageContentModeAspectFit options:option resultHandler:^(PHLivePhoto * _Nullable livePhoto, NSDictionary * _Nullable info) {
        if (completion) completion(livePhoto, info);
    }];

播放LivePhoto则需要借助系统框架 PhotosUI.framework

,我们直接把上边block中请求的PHLivePhoto类型对象赋值给  PHLivePhotoView 类的UI即可, 调用  startPlaybackWithStyle: 方法即可进行播放





10.获取Video


[[PHCachingImageManager defaultManager] requestPlayerItemForVideo:asset options:nil resultHandler:^(AVPlayerItem * _Nullable playerItem, NSDictionary * _Nullable info) {
        if (completion) completion(playerItem, info);
    }];

播放视频则需要使用  AVPlayerLayer,使用对应方法播放即可