iOS 14使用PHPhotoLibrary获取图片库

之前项目使用UIImagePickerController获取相册。由于iOS 14升级了图片库权限,多了PHAuthorizationStatusLimited权限。为了适应升级,需要用PHPhotoLibrary获取相册。

一、 使用PHPickerViewController显示图片库

<PhotosUI/PhotosUI.h>中提供了PHPickerViewController。可以直接使用,用于显示照片库。带原生的搜索功能(很强大)。但是Limited权限,显示全部照片而非部分。

@interface PHPickerViewController : UIViewController
/// The delegate to be notified.
@property (NS_NONATOMIC_IOSONLY, weak) id<PHPickerViewControllerDelegate> delegate NS_REFINED_FOR_SWIFT;
/// Initializes new picker with the \c configuration the picker should use.
- (instancetype)initWithConfiguration:(PHPickerConfiguration *)configuration NS_DESIGNATED_INITIALIZER NS_REFINED_FOR_SWIFT;
@end
1.先声明PHPickerConfiguration
@interface PHPickerConfiguration : NSObject <NSCopying>
//转码模式
@property (NS_NONATOMIC_IOSONLY) PHPickerConfigurationAssetRepresentationMode preferredAssetRepresentationMode;
//可选择的照片数
@property (NS_NONATOMIC_IOSONLY) NSInteger selectionLimit;
//筛选模式设置,目前可以指定筛选照片、视频、LivePhoto 几种类型,或者任何他们的组合。
@property (NS_NONATOMIC_IOSONLY, copy, nullable) PHPickerFilter *filter;
@end
2.使用Delegate获取照片
@protocol PHPickerViewControllerDelegate <NSObject>
- (void)picker:(PHPickerViewController *)picker didFinishPicking:(NSArray<PHPickerResult *> *)results;
@end
3.代码
//跳转代码
PHPickerConfiguration *config = [[PHPickerConfiguration alloc] initWithPhotoLibrary:[PHPhotoLibrary sharedPhotoLibrary]];
config.filter = [PHPickerFilter imagesFilter];
config.selectionLimit = 1;
self.pickerVC = [[PHPickerViewController alloc] initWithConfiguration:config];
self.pickerVC.delegate = self;
self.pickerVC.modalPresentationStyle = UIModalPresentationFullScreen;
[self presentViewController:self.pickerVC animated:YES completion:^{}];


//代理
- (void)picker:(PHPickerViewController *)picker didFinishPicking:(NSArray<PHPickerResult *> *)results
{
    if (results.count<=0) {//点击返回
        
    }else{
        PHPickerResult *imgResult = [results objectAtIndex:0];//可多选
        if ([imgResult.itemProvider canLoadObjectOfClass:UIImage.class]) {
            [imgResult.itemProvider loadObjectOfClass:[UIImage class] completionHandler:^(__kindof id<NSItemProviderReading>  _Nullable object, NSError * _Nullable error) {
                dispatch_async(dispatch_get_main_queue(), ^{
                    UIImage *image = object;
                });
            }];
        }
    }
    [self.pickerVC dismissViewControllerAnimated:YES completion:nil];
}

二、使用PHFetchResult获取图片

PHFetchResult可以获取到有限照片库权限的照片。如果此时权限是全部,则返回全部照片。这种方法只能自己写UI去显示。

1.获取相册数据

1.1PHFetchResult

// Accessing fetched results (fetches objects from the backing store in chunks on demand rather than all at once)
// Fetched objects will be kept in a cache and purged under memory pressure
//访问获取的结果(按需从备份存储中获取对象,而不是一次获取所有对象)
//获取的对象将保存在缓存中,并在内存压力下清除

PHFetchResult *smartAlbums = [PHAssetCollection fetchAssetCollectionsWithType:PHAssetCollectionTypeSmartAlbum subtype:PHAssetCollectionSubtypeSmartAlbumUserLibrary options:nil];

其中PHAssetCollection一个该实例对象代表一个相册。是PHCollection的子类。

typedef NS_ENUM(NSInteger, PHAssetCollectionType) {
 PHAssetCollectionTypeAlbum      = 1,照片应用程序中的相册 //An album in the Photos app. 
 PHAssetCollectionTypeSmartAlbum = 2,内容动态更新的智能相册。//  A smart album whose contents update dynamically.
 PHAssetCollectionTypeMoment   API_DEPRECATED("Will be removed in a future release", ios(8, 13), tvos(10, 13)) = 3, // A moment in the Photos app.
 }

PHAssetCollectionSubtype
1.User Album Types

 // PHAssetCollectionTypeAlbum regular subtypes
 PHAssetCollectionSubtypeAlbumRegular         = 2, 在iPhone中自己创建的相册// An album created in the Photos app. 
 PHAssetCollectionSubtypeAlbumSyncedEvent     = 3, 从iPhoto(就是iMac上的图片app)中导入图片到设备//An Event synced to the device from iPhoto.
 PHAssetCollectionSubtypeAlbumSyncedFaces     = 4, 从图片app中导入的人物照片// A Faces group synced to the device from iPhoto.
 PHAssetCollectionSubtypeAlbumSyncedAlbum     = 5, 从图片app导入的相册// An album synced to the device from iPhoto. 
 PHAssetCollectionSubtypeAlbumImported        = 6, 从其他的相机或者存储设备导入的相册// An album imported from a camera or external storage. 

2.Cloud Album Types

// PHAssetCollectionTypeAlbum shared subtypes
PHAssetCollectionSubtypeAlbumMyPhotoStream   = 100,  用户的照片流,如果在设置里关闭了iCloud开关,就获取不到了。//The user’s personal iCloud Photo Stream.
PHAssetCollectionSubtypeAlbumCloudShared     = 101,  iCloud的共享相册,点击照片上的共享tab创建后就能拿到了,但是前提是你要在设置中打开iCloud的共享开关(打开后才能看见共享tab)// An iCloud Shared Photo Stream.

3.Smart Album Types

 // PHAssetCollectionTypeSmartAlbum subtypes
 PHAssetCollectionSubtypeSmartAlbumGeneric    = 200,一个没有更多特定子类型的智能相册。//A smart album of no more specific subtype.
 PHAssetCollectionSubtypeSmartAlbumPanoramas  = 201,  一个智能相册,将照片库中的所有全景照片分组。// A smart album that groups all panorama photos in the photo library.
 PHAssetCollectionSubtypeSmartAlbumVideos     = 202, 将照片库中的所有视频资产分组的智能相册。//A smart album that groups all video assets in the photo library.
 PHAssetCollectionSubtypeSmartAlbumFavorites  = 203,  标记为喜欢、收藏 //A smart album that groups all assets that the user has marked as favorites.
 PHAssetCollectionSubtypeSmartAlbumTimelapses = 204, 延时拍摄、定时拍摄// A smart album that groups all time-lapse videos in the photo library. 
 PHAssetCollectionSubtypeSmartAlbumAllHidden  = 205,   一个智能相册,将照片应用程序的“时刻”视图中隐藏的所有资产分组。//A smart album that groups all assets hidden from the Moments view in the Photos app.
 PHAssetCollectionSubtypeSmartAlbumRecentlyAdded = 206, 最近添加的 //A smart album that groups assets that were recently added to the photo library.
 PHAssetCollectionSubtypeSmartAlbumBursts     = 207,  连拍//A smart album that groups all burst photo sequences in the photo library. 
 PHAssetCollectionSubtypeSmartAlbumSlomoVideos = 208,  所有慢镜头视频// A smart album that groups all Slow-Mo videos in the photo library.
 PHAssetCollectionSubtypeSmartAlbumUserLibrary = 209, 一个智能相册,它将来自用户自己库的所有资产(与iCloud共享相册中的资产不同)。//A smart album that groups all assets that originate in the user’s own library (as opposed to assets from iCloud Shared Albums).
 PHAssetCollectionSubtypeSmartAlbumSelfPortraits = 210, 使用前置摄像头拍摄的作品 //A smart album that groups all photos and videos captured using the device’s front-facing camera.
 PHAssetCollectionSubtypeSmartAlbumScreenshots = 211,  屏幕截图 //A smart album that groups all images captured using the device’s screenshot function.
 PHAssetCollectionSubtypeSmartAlbumDepthEffect = 212,  在可兼容的设备上使用景深模式拍的照片(人像模式) //A smart album that groups all images captured using the Depth Effect camera mode on compatible devices.
 PHAssetCollectionSubtypeSmartAlbumLivePhotos = 213,  Live Photo资源 //A smart album that groups all Live Photo assets.
 PHAssetCollectionSubtypeSmartAlbumAnimated = 214,  将所有图像动画资源分组的智能相册。//A smart album that groups all image animation assets.
 PHAssetCollectionSubtypeSmartAlbumLongExposures = 215,  启用长曝光变化的所有Live Photo资源 //A smart album that groups all Live Photo assets where the Long Exposure variation is enabled. 
 // Used for fetching, if you don't care about the exact subtype
 PHAssetCollectionSubtypeAny = NSIntegerMax
2.实现代码
2.1获取所有照片
PHFetchOptions *option = [[PHFetchOptions alloc] init];
//ascending 为YES时,按照照片的创建时间升序排列;为NO时,则降序排列
option.sortDescriptors = @[[NSSortDescriptor sortDescriptorWithKey:@"creationDate" ascending:NO]];
self.fetchList = [PHAsset fetchAssetsWithMediaType:PHAssetMediaTypeImage options:option];//PHFetchResult这个类型可以当成NSArray使用。此时所有可获取照片都已拿到,可以刷新UI进行显示
2.2按顺序获取照片显示
PHImageRequestOptions *options = [[PHImageRequestOptions alloc] init];
    options.synchronous = true;
    options.deliveryMode = PHImageRequestOptionsDeliveryModeHighQualityFormat;
    options.networkAccessAllowed = YES;
    [[PHImageManager defaultManager] requestImageDataAndOrientationForAsset:[self.fetchList objectAtIndex:indexPath.row] options:options resultHandler:^(NSData * _Nullable imageData, NSString * _Nullable dataUTI, CGImagePropertyOrientation orientation, NSDictionary * _Nullable info)
    {
        UIImage *image = [UIImage imageWithData:imageData];
    }];

参考:
1.照片框架 https://objccn.io/issue-21-4/
2.Photo Frameworks之PHAssetCollection、PHCollectionList和PHAsset https://www.jianshu.com/p/ac3d7f490f82

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 206,839评论 6 482
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 88,543评论 2 382
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 153,116评论 0 344
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 55,371评论 1 279
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 64,384评论 5 374
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,111评论 1 285
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,416评论 3 400
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,053评论 0 259
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 43,558评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,007评论 2 325
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,117评论 1 334
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,756评论 4 324
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,324评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,315评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,539评论 1 262
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,578评论 2 355
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,877评论 2 345