美文网首页iOS常用
iOS 14使用PHPhotoLibrary获取图片库

iOS 14使用PHPhotoLibrary获取图片库

作者: 左方 | 来源:发表于2020-10-29 17:05 被阅读0次

    之前项目使用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获取所有照片
    PHFetchResult *fetchResult = [PHAsset fetchAssetsWithOptions:nil];
        if (fetchResult.count > 0) {
            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

    相关文章

      网友评论

        本文标题:iOS 14使用PHPhotoLibrary获取图片库

        本文链接:https://www.haomeiwen.com/subject/noezpktx.html