美文网首页图片相关
iOS 14适配相册权限

iOS 14适配相册权限

作者: 杏子_2fd0 | 来源:发表于2021-06-25 16:51 被阅读0次

         最近需要适配iOS 14的相册权限,在网上查了很多资料,大部分资料都只讲一部分缺另一部分,想把整个相册权限适配好还是有点麻烦,现在办把我整个适配过程记录下来,需要适配的兄弟可以参考一下

         在 iOS13 及以前,当用户首次访问应用程序时,会被要求开放大量权限,比如相册、定位、联系人,实际上该应用可能仅仅需要一个选择图片功能,却被要求开放整个照片库的权限,这确实是不合理的。对于相册,在 iOS14 中引入了 “LimitedPhotos Library” 的概念,用户可以授予应用访问其一部分的照片,对于应用来说,仅能读取到用户选择让应用来读取的照片,让我们看到了 Apple 对于用户隐私的尊重。这仅仅是一部分,在iOS14 中,可以看到诸多类似的保护用户隐私的措施,也需要我们升级适配。 

          iOS14 新增了“Limited Photo Library Access” 模式,在授权弹窗中增加了 Select Photo 选项。用户可以在 App 请求调用相册时选择部分照片让 App 读取。从 App 的视⻆来看,你的相册里就只有这几张照片,App 无法得知其它照片的存在。

       当一下次在进入时有会弹提示框,让你选择更多图片或者保留当前选择,这个提示框不太友好,可以在plist文件里面通过设置 Prevent limited photos access alert = YES隐藏提示

    当选择添加更多图片是,可以通过    [[PHPhotoLibrary sharedPhotoLibrary] presentLimitedLibraryPickerFromViewController:self];到相册添加删除图片,然后监听图片变化做相应处理。

    对于PHAuthorizationStatusLimited权限的适配,我采用的方案是,先绘制一个列表用于显示授权的图片,图片的资源也就是授权访问的,当要添加更多图片是通过 [[PHPhotoLibrary sharedPhotoLibrary] presentLimitedLibraryPickerFromViewController:self];跳转到相册,添加图片,添加完成后监听图片变化,更新列表,下面是我的代码:

     if (@available(iOS 14.0, *)) {

                PHAuthorizationStatus status = [PHPhotoLibrary authorizationStatusForAccessLevel:PHAccessLevelReadWrite];

                  switch(status) {

                      case PHAuthorizationStatusNotDetermined:

                          [self dispatchAuthorizationForAccessLevel];

                          break;

                      case PHAuthorizationStatusLimited:

                          NSLog(@"limited");

                          [selfe_enterGDPickerVC];

                          break;

                          // 用户拒绝当前应用访问相册

                      case PHAuthorizationStatusDenied:

                          NSLog(@"denied");

                          [self disptachPHAuthorizationStatusDenied];

                          break;

                          // 用户允许当前应用访问相册

                      case PHAuthorizationStatusAuthorized:

                          NSLog(@"authorized");

                          [self P_enterPHPickerViewController];

                          break;

                      default:

                          break;

                }

            }

    /用户第一次访问

    -(void)dispatchAuthorizationForAccessLevel{

        [PHPhotoLibrary requestAuthorizationForAccessLevel:PHAccessLevelReadWrite handler:^(PHAuthorizationStatus status) {

                    switch(status) {

                        case PHAuthorizationStatusLimited:

                        {

                            dispatch_async(dispatch_get_main_queue(), ^{

                                [selfe_enterGDPickerVC];

                            });

                            break;

                        }

                        case PHAuthorizationStatusDenied:

                        {

                            NSLog(@"denied");

                        }

                            break;

                        case PHAuthorizationStatusAuthorized:

                        {

                        }

                            break;

                        default:

                            break;

                    }

                }];

    }

    //进入授权访问的图片控制器

    -(void)e_enterGDPickerVC{

        MJWeakSelf;

        GDPickerVC *picker = [GDPickerVC new];

        picker.currentImageContent= ^(UIImage*_NonnullimageContent) {

            NSLog(@"--选择图片--");

            if(!imageContent) {

                return;

            }

            [weakSelfanalysisImageWithContent:imageContent];

        };

        UINavigationController *nv = [[UINavigationController alloc] initWithRootViewController:picker];

        nv.modalPresentationStyle  =0;

        [_controller presentViewController:nv animated:YES completion:nil];

    }

    ----------授权图片列表--------------

    //

    //

    #import "GDPickerVC.h"

    #import

    #import "GDPickerCollectionViewCell.h"

    #define SCREEN_WIDTH ([[UIScreen mainScreen] bounds].size.width)

    // 屏幕高度,会根据横竖屏的变化而变化

    #define SCREEN_HEIGHT ([[UIScreen mainScreen] bounds].size.height)

    @interface GDPickerVC ()<UICollectionViewDataSource,UICollectionViewDelegateFlowLayout>

    @property (nonatomic, strong) UICollectionView *collectionView;

    @property (nonatomic, strong) NSMutableArray *photoArray;

    @end

    @implementation GDPickerVC

    - (void)viewDidLoad {

        [super viewDidLoad];

        self.view.backgroundColor = [UIColor whiteColor];

        self.title = @"显示允许访问的图片";

        //左边返回按钮

        UIButton *fanHuiButton = [UIButton buttonWithType:UIButtonTypeCustom];

        fanHuiButton.frame=CGRectMake(0,0,30,40);

        [fanHuiButtonsetTitle:@"取消"forState:0];

        [fanHuiButtonsetTitleColor:[UIColor systemBlueColor] forState:0];

        [fanHuiButtonaddTarget:self action:@selector(comebackFuncation) forControlEvents:UIControlEventTouchUpInside];

        UIBarButtonItem *leftItem = [[UIBarButtonItem alloc] initWithCustomView:fanHuiButton];

        self.navigationItem.leftBarButtonItem = leftItem;

        UIButton *rightButton = [UIButton buttonWithType:UIButtonTypeCustom];

        rightButton.frame=CGRectMake(0,0,30,40);

        [rightButtonsetTitle:@"添加"forState:0];

        [rightButtonsetTitleColor:[UIColor systemBlueColor] forState:0];

        [rightButtonaddTarget:self action:@selector(confirmButton:) forControlEvents:UIControlEventTouchUpInside];

        UIBarButtonItem *rightItem = [[UIBarButtonItem alloc] initWithCustomView:rightButton];

        self.navigationItem.rightBarButtonItem = rightItem;

        //获取图片

        [self getLibarayPhotoImage];

        self.photoArray = [NSMutableArray array];

        [self.view addSubview:self.collectionView];

    }

    #pragma mark - UICollectionViewDataSource

    - (CGSize)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout*)collectionViewLayout sizeForItemAtIndexPath:(NSIndexPath *)indexPath

    {

        return CGSizeMake(SCREEN_WIDTH/3-2,SCREEN_WIDTH/3);

    }

    - (NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section {

        return self.photoArray.count;

    }

    - (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath {

        UIImage*image =self.photoArray[indexPath.row];

        GDPickerCollectionViewCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:NSStringFromClass(GDPickerCollectionViewCell.class) forIndexPath:indexPath];

        cell.imgView.image= image;

        returncell;

    }

    - (void)collectionView:(UICollectionView *)collectionView didSelectItemAtIndexPath:(NSIndexPath *)indexPath{

        UIImage*image =self.photoArray[indexPath.row];

        if (_currentImageContent&&image) {

            _currentImageContent(image);

            [self comebackFuncation];

        }

    }

    #pragma response

    //返回

    -(void)comebackFuncation{

        [self dismissViewControllerAnimated:YES completion:nil];

    }

    //点击确认回调数据

    -(void)confirmButton:(UIButton *)btn{

        [[PHPhotoLibrary sharedPhotoLibrary] presentLimitedLibraryPickerFromViewController:self];

        [[PHPhotoLibrary sharedPhotoLibrary] registerChangeObserver:self];

    }

    - (void)photoLibraryDidChange:(PHChange *)changeInstance

    {

        [self.photoArray removeAllObjects];

        [self getLibarayPhotoImage];

    }

    /*  遍历相簿中的全部图片

    *  @param assetCollection 相簿

    *  @param original        是否要原图

    */

    -(void)getLibarayPhotoImage01{

        __weaktypeof(self) weakSelf =self;

        NSMutableArray<UIImage *> *images = [NSMutableArray array];

        //获取可访问的图片配置选项

        PHFetchOptions *option = [[PHFetchOptions alloc] init];

        //根据图片的创建时间升序排序返回

        option.sortDescriptors = @[[NSSortDescriptor sortDescriptorWithKey:@"creationDate" ascending:YES]];

        //获取类型为image的资源

        PHFetchResult *result = [PHAsset fetchAssetsWithMediaType:PHAssetMediaTypeImage options:option];

         //遍历出每个PHAsset资源对象

        [resultenumerateObjectsUsingBlock:^(id  _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {

            PHAsset*asset = (PHAsset*)obj;

            //将PHAsset解析为image的配置选项

            PHImageRequestOptions *requestOptions = [[PHImageRequestOptions alloc] init];

            //图像缩放模式

            requestOptions.resizeMode = PHImageRequestOptionsResizeModeExact;

            //图片质量

            requestOptions.deliveryMode = PHImageRequestOptionsDeliveryModeHighQualityFormat;

            //PHImageManager解析图片

            [[PHImageManager defaultManager] requestImageForAsset:asset targetSize:PHImageManagerMaximumSize contentMode:PHImageContentModeDefault options:requestOptions resultHandler:^(UIImage * _Nullable result, NSDictionary * _Nullable info) {

                NSLog(@"图片 %@",result);

                //在这里可以自定义一个显示可访问相册资源的viewController.

                if(result) {

                    [weakSelf.photoArrayaddObject:result];

                }

            }];

            dispatch_async(dispatch_get_main_queue(), ^{

                [self.collectionView reloadData];

            });

        }];

    }

    -(void)getLibarayPhotoImage{

        dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{

            PHFetchResult<PHAssetCollection *> *assetCollections = [PHAssetCollection fetchAssetCollectionsWithType:PHAssetCollectionTypeAlbum subtype:PHAssetCollectionSubtypeAlbumRegular options:nil];

            for(PHAssetCollection*assetCollectioninassetCollections) {

                [self enumerateAssetsInAssetCollection:assetCollection original:YES];

            }

            PHAssetCollection *cameraRoll = [PHAssetCollection fetchAssetCollectionsWithType:PHAssetCollectionTypeSmartAlbum subtype:PHAssetCollectionSubtypeSmartAlbumUserLibrary options:nil].lastObject;

            [self enumerateAssetsInAssetCollection:cameraRoll original:YES];

        });

    }

    - (void)enumerateAssetsInAssetCollection:(PHAssetCollection *)assetCollectionoriginal:(BOOL)original

    {

       PHImageRequestOptions *options = [[PHImageRequestOptions alloc] init];

       options.resizeMode = PHImageRequestOptionsResizeModeFast;

       options.synchronous=YES;

       PHFetchResult<PHAsset *> *assets = [PHAsset fetchAssetsInAssetCollection:assetCollection options:nil];

       for(PHAsset*assetinassets) {

           CGSize size = original ? CGSizeMake(asset.pixelWidth, asset.pixelHeight) : CGSizeZero;

           __weaktypeof(self) weakSelf =self;

           [[PHImageManager defaultManager] requestImageForAsset:asset targetSize:size contentMode:PHImageContentModeDefault options:options resultHandler:^(UIImage * _Nullable result, NSDictionary * _Nullable info) {

               NSLog(@"%@", result);

               if(result) {

                   original ? [weakSelf.photoArrayaddObject:result] : [weakSelf.photoArrayaddObject:result];

               }

           }];

           dispatch_async(dispatch_get_main_queue(), ^{

               [weakSelf.collectionViewreloadData];

           });

       }

    }

    #pragma mark--懒加载

    - (UICollectionView *)collectionView{

        if (!_collectionView) {

            UICollectionViewFlowLayout *flowLayout = [[UICollectionViewFlowLayout alloc] init];

            flowLayout.minimumLineSpacing=2;

            flowLayout.minimumInteritemSpacing = 1;

            UICollectionView *collectionView = [[UICollectionView alloc] initWithFrame:self.view.bounds collectionViewLayout:flowLayout];

            collectionView.backgroundColor = self.view.backgroundColor;

            collectionView.delegate=self;

            collectionView.dataSource=self;

            [collectionViewregisterClass:GDPickerCollectionViewCell.class forCellWithReuseIdentifier:NSStringFromClass(GDPickerCollectionViewCell.class)];

            _collectionView= collectionView;

        }

        return _collectionView;

    }

    @end

    上面是PHAuthorizationStatusLimited 用户已授权此应用程序进行有限照片库访问(iOS14新增)的适配,下面在来说一下适配允许访问所有图片,下面是适配代码

    //ios14后使用

    -(void)P_enterPHPickerViewController{

        MJWeakSelf;

        //用户选择"允许访问所有照片",调用PHPickerViewController显示图片选择器

        dispatch_async(dispatch_get_main_queue(), ^{

            PHPickerConfiguration *configuration = [[PHPickerConfiguration alloc] init];

            //只获取image类型资源

            configuration.filter = [PHPickerFilter imagesFilter];

             //可以多选

    //        configuration.selectionLimit = 1;

            PHPickerViewController *pickerVC = [[PHPickerViewController alloc] initWithConfiguration:configuration];

            pickerVC.delegate=self;

            pickerVC.modalPresentationStyle = UIModalPresentationFullScreen;

            [weakSelf.controller presentViewController:pickerVC animated:YES completion:^{

            }];

        });

    }

    - (void)picker:(PHPickerViewController *)picker didFinishPicking:(NSArray<PHPickerResult *> *)results

    {

        MJWeakSelf;

        [pickerdismissViewControllerAnimated:YES completion:nil];

        if(!results || !results.count) {

            return;

        }

        NSLog(@"didFinishPicking");

        NSItemProvider *itemProvider = results.firstObject.itemProvider;

             if ([itemProvider canLoadObjectOfClass:UIImage.class]) {

                 __weaktypeof(self) weakSelf =self;

                 [itemProviderloadObjectOfClass:UIImage.class completionHandler:^(__kindof id<NSItemProviderReading>  _Nullable object, NSError * _Nullable error) {

                     if([objectisKindOfClass:UIImage.class]) {

                         UIImage*image = (UIImage*)object;

                         [weakSelfanalysisImageWithContent:image];

                     }

                 }];

             }

    }

    相关文章

      网友评论

        本文标题:iOS 14适配相册权限

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