iOS14 適配相冊Limited模式

前言

蘋果在iOS14繼續(xù)加強了對用戶隱私的保護,有時需求只是想選擇一張相冊中的圖片,但是需要對App開發(fā)整個照片庫的權(quán)限,一些私密照片也可以被App讀取到,這樣很不合理!因此iOS14中對相冊權(quán)限新增了“Limited Photo Library Access” 模式,這樣用戶可以控制App允許訪問的照片。下面簡單介紹下如何適配iOS14相冊新增的功能。

相冊相關(guān)庫

iOS8以后蘋果逐漸使用Photos代替AssetsLibrary,這里主要使用Photos實現(xiàn)訪問系統(tǒng)相冊。如果還在使用AssetsLibrary請盡快使用新的 API實現(xiàn)相冊相關(guān)功能。項目中需要引入Photos和PhotoUI庫。

權(quán)限彈窗變化

  • Select Photo(選擇照片): 限制訪問,點擊之后會彈出系統(tǒng)的圖片選擇界面選擇資源,APP 只能訪問用戶選擇的資源。
  • Allow Access to All Photos(允許訪問所有照片): 可以訪問所有的資源。
  • Don't Allow(不允許): 不允許訪問資源
圖片

PHPhotoLibrary新增API

PHPhotoLibrary用于獲取查看相冊權(quán)限,處理相冊變化,注冊監(jiān)聽相冊變化,監(jiān)聽用戶添加/刪除了哪些照片。

  • 權(quán)限枚舉

PHAuthorizationStatusNotDetermined 用戶未作出選擇

PHAuthorizationStatusRestricted 此App無權(quán)限訪問照片數(shù)據(jù)

PHAuthorizationStatusDenied 用戶已明確拒絕此應(yīng)用程序訪問照片數(shù)據(jù)

PHAuthorizationStatusAuthorized 用戶已授權(quán)此應(yīng)用程序訪問照片數(shù)據(jù)

PHAuthorizationStatusLimited 用戶已授權(quán)此應(yīng)用程序進行有限照片庫訪問(iOS14新增)

  • 權(quán)限等級枚舉

PHAccessLevelAddOnly 僅允許添加

PHAccessLevelReadWrite 讀寫

注意:PHAuthorizationStatusLimited 權(quán)限只在 accessLevel 為 PHAccessLevelReadWrite 時生效

  • 權(quán)限獲取

新權(quán)限獲?。涸黾恿藱?quán)限等級

+ (PHAuthorizationStatus)authorizationStatusForAccessLevel:(PHAccessLevel)accessLevel
+ (void)requestAuthorizationForAccessLevel:(PHAccessLevel)accessLevel handler:(void(^)(PHAuthorizationStatus status))handler 

舊權(quán)限獲取:在iOS14中已經(jīng)廢棄,建議使用上面的新API

+ (PHAuthorizationStatus)authorizationStatus 
+ (void)requestAuthorization:(void(^)(PHAuthorizationStatus status))handler 

注意:如果仍使用舊的API未適配iOS14新特性,這時獲取相冊權(quán)限狀態(tài),就算在Limited 模式下也會返回Authorized

  • 新增PHPicker

iOS 14 中系統(tǒng)新增了一個圖片選擇器PHPicker(iOS14以上使用),官方建議使用 PHPicker 來替代原有的UIImagePickerController(iOS14以下使用)進行圖片選擇 。UIImagePickerController只能選中一張圖片已經(jīng)不符合需求了,將逐漸被廢棄替換。

怎樣使用PHPicker

圖片

1、使用PHPickerConfiguration配置PHPicker,鍵selectionLimit 設(shè)置為0表示多選,設(shè)置為大于1表示只可選中一張圖片,默認值為1;使用filter設(shè)置想要的相冊資源類型,包括imagesFilter、videosFilter、livePhotosFilter,亦可以設(shè)置為數(shù)組@[videoFilter,livePhotosFilter]顯示多種類型.
2、設(shè)置PHPickerViewControllerDelegate代理,接收選中照片后的回調(diào);
3、在代理回調(diào)piscker:didFinishPicking: 中處理返回結(jié)果PHPickerResult;

PHPicker優(yōu)缺點

優(yōu)點:

  1. 支持多選,可以設(shè)置選擇一個資源,還是多個資源;
  2. 支持按 image,video,livePhotos 類型進行選擇;
  3. 只是資源搜索,在頁面上有搜索框;
  4. 獨立進程,不會影響App性能,如何體現(xiàn)呢:在設(shè)置→照片→照片權(quán)限設(shè)置中選擇點擊”選中的照片“后也會彈出PHPicker,并且可以為App添加允許訪問的照片;
  5. 內(nèi)置隱私:不需要直接訪問用戶相冊;不會彈出訪問相冊提示;僅為用戶提供選擇的照片和視頻(App 無法獲取其他照片);

缺點:

  1. 不支持選中圖片的編輯,例如選中后裁剪成正方形,需要自定義實現(xiàn)了;

plist設(shè)置

NSPhotoLibraryAddUsageDescription

用戶存入相冊時的提示信息。

NSPhotoLibraryUsageDescription

相冊訪問權(quán)限信息,必須有此項,不然訪問相冊的時候 APP 會 Crash。

PHPhotoLibraryPreventAutomaticLimited

如果未適配,App在每次冷啟動時都會觸發(fā)詢問用戶是否需要修改照片權(quán)限,添加可供App訪問的圖片。

圖片

隱藏系統(tǒng)彈出的選擇圖片Alert

在首次啟動訪問相冊權(quán)限,并且選擇了Limited權(quán)限后,再次冷啟動的時候會自動彈出權(quán)限選擇Alert,要求用戶選擇圖片。

圖片

在info.plist中加入PHPhotoLibraryPreventAutomaticLimited = YES關(guān)閉系統(tǒng)自動彈窗。并且使用下面的API主動調(diào)用控制彈出PHPickerViewController 進行照片選擇。(在應(yīng)該使用的地方使用)

  [[PHPhotoLibrary sharedPhotoLibrary] presentLimitedLibraryPickerFromViewController:self];

使用示例

  • 查詢權(quán)限
PHAuthorizationStatus status = [PHPhotoLibrary authorizationStatusForAccessLevel:PHAccessLevelReadWrite];
  switch (status) {
      case PHAuthorizationStatusLimited:
          NSLog(@"limited");
          break;
      case PHAuthorizationStatusDenied:
          NSLog(@"denied");
          break;
      case PHAuthorizationStatusAuthorized:
          NSLog(@"authorized");
          break;
      default:
          break;
}
  • 請求權(quán)限
[PHPhotoLibrary requestAuthorizationForAccessLevel:PHAccessLevelReadWrite handler:^(PHAuthorizationStatus status) {
            switch (status) {
                case PHAuthorizationStatusLimited:
                {
                    //用戶選擇Limited模式,限制App訪問有限的相冊資源
                    NSMutableArray<UIImage *> *images = [NSMutableArray array];
                    //獲取可訪問的圖片配置選項
                    PHFetchOptions *option = [[PHFetchOptions alloc] init];
                    //根據(jù)圖片的創(chuàng)建時間升序排序返回
                    option.sortDescriptors = @[[NSSortDescriptor sortDescriptorWithKey:@"creationDate" ascending:YES]];
                    //獲取類型為image的資源
                    PHFetchResult *result = [PHAsset fetchAssetsWithMediaType:PHAssetMediaTypeImage options:option];
                     //遍歷出每個PHAsset資源對象
                    [result enumerateObjectsUsingBlock:^(id  _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {
                        PHAsset *asset = (PHAsset *)obj;
                        //將PHAsset解析為image的配置選項
                        PHImageRequestOptions *requestOptions = [[PHImageRequestOptions alloc] init];
                        //圖像縮放模式
                        requestOptions.resizeMode = PHImageRequestOptionsResizeModeExact;
                        //圖片質(zhì)量
                        requestOptions.deliveryMode = PHImageRequestOptionsDeliveryModeHighQualityFormat;
                        //PHImageManager解析圖片
                        [[PHImageManager defaultManager] requestImageForAsset:asset targetSize:PHImageManagerMaximumSize contentMode:PHImageContentModeDefault options:requestOptions resultHandler:^(UIImage * _Nullable result, NSDictionary * _Nullable info) {
                            NSLog(@"圖片 %@",result);
                            //在這里可以自定義一個顯示可訪問相冊資源的viewController.
                            [images addObject:result];
                        }];
                    }];
                    break;
                }
                case PHAuthorizationStatusDenied:
                {
                    NSLog(@"denied");
                }
                    break;
                case PHAuthorizationStatusAuthorized:
                {
                    //用戶選擇"允許訪問所有照片",調(diào)用PHPickerViewController顯示圖片選擇器
                    dispatch_async(dispatch_get_main_queue(), ^{
                        PHPickerConfiguration *configuration = [[PHPickerConfiguration alloc] init];
                        //只獲取image類型資源
                        configuration.filter = [PHPickerFilter imagesFilter];
                         //可以多選
                        configuration.selectionLimit = 0;
                        PHPickerViewController *pickerVC = [[PHPickerViewController alloc] initWithConfiguration:configuration];
                        pickerVC.delegate = self;
                        pickerVC.modalPresentationStyle = UIModalPresentationFullScreen;
                        [self presentViewController:pickerVC animated:YES completion:^{
                        }];
                    });  
                }
                    break;
                default:
                    break;
            }
        }];

返回結(jié)果:選中了三張圖片允許App訪問


圖片

注意: 我們通過requestImageForAsset獲取到允許訪問的圖片PHAsset對象后,解析為UIImage后,需要開發(fā)者自定義一個顯示可訪問相冊資源的viewController.

  • 主動彈出選擇照片PHPickerViewController
[[PHPhotoLibrary sharedPhotoLibrary] presentLimitedLibraryPickerFromViewController:self];
  • 選中圖片后的回調(diào)
- (void)picker:(PHPickerViewController *)picker didFinishPicking:(NSArray<PHPickerResult *> *)results
{
    [picker dismissViewControllerAnimated:YES completion:nil];
    if (!results || !results.count) {
        return;
    }
    NSLog(@"didFinishPicking");
}

注意:無論我們點擊完成還是取消都會調(diào)用這個回調(diào),當點擊取消時results返回為空

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容