iOS14 相册更新

2021-10-08  本文已影响0人  whlpkk

前言

苹果在iOS14继续加强了对用户隐私的保护,有时需求只是想选择一张相册中的图片,但是需要对App开发整个照片库的权限,一些私密照片也可以被App读取到,这样很不合理!因此iOS14中对相册权限新增了 "Limited Photo Library Access" 模式,这样用户可以控制App允许访问的照片。下面简单介绍下如何适配iOS14相册新增的功能。

PHPhotoLibrary新增API

PHPhotoLibrary用于获取查看相册权限,处理相册变化,注册监听相册变化,监听用户添加/删除了哪些照片。

typedef NS_ENUM(NSInteger, PHAuthorizationStatus) {
    PHAuthorizationStatusNotDetermined = 0, // 用户未作出选择
    PHAuthorizationStatusRestricted,        // 此App无权限访问照片数据
    PHAuthorizationStatusDenied,            // 用户已明确拒绝此应用程序访问照片数据
    PHAuthorizationStatusAuthorized,        // 用户已授权此应用程序访问照片数据
    PHAuthorizationStatusLimited API_AVAILABLE(ios(14)), // 用户已授权此应用程序进行有限照片库访问
};  
typedef NS_ENUM(NSInteger, PHAccessLevel) {
    PHAccessLevelAddOnly = 1,     // 仅允许添加
    PHAccessLevelReadWrite = 2,   // 读写
} API_AVAILABLE(macos(11.0), ios(14), tvos(14));

新权限获取:增加了权限等级

// 获取指定等级的权限
+ (PHAuthorizationStatus)authorizationStatusForAccessLevel:(PHAccessLevel)accessLevel API_AVAILABLE(macosx(11.0), ios(14), tvos(14));

// 请求指定等级的权限
+ (void)requestAuthorizationForAccessLevel:(PHAccessLevel)accessLevel handler:(void(^)(PHAuthorizationStatus status))handler API_AVAILABLE(macosx(11.0), ios(14), tvos(14)) NS_SWIFT_ASYNC(2);

旧权限获取:在iOS14中已经废弃,建议使用上面的新API

+ (PHAuthorizationStatus)authorizationStatus API_DEPRECATED_WITH_REPLACEMENT("+authorizationStatusForAccessLevel:", ios(8, API_TO_BE_DEPRECATED), macos(10.13, API_TO_BE_DEPRECATED), tvos(10, API_TO_BE_DEPRECATED));

+ (void)requestAuthorization:(void(^)(PHAuthorizationStatus status))handler API_DEPRECATED_WITH_REPLACEMENT("+requestAuthorizationForAccessLevel:handler:", ios(8, API_TO_BE_DEPRECATED), macos(10.13, API_TO_BE_DEPRECATED), tvos(10, API_TO_BE_DEPRECATED));

注意:如果仍使用旧的API未适配iOS14新特性,这时获取相册权限状态,就算在Limited 模式下也会返回Authorized

新增 PHPickerController

iOS 14 中系统新增了一个图片选择器PHPicker ( iOS14 以上使用),官方建议使用 PHPicker 来替代原有的 UIImagePickerController ( iOS14 以下使用)进行图片选择 。UIImagePickerController 只能选中一张图片已经不符合需求了,将逐渐被废弃替换。

1.png
  1. 使用 PHPickerConfiguration 配置 PHPicker,键 selectionLimit 设置为 n 表示最多可选中 n 张图片,0 为 maximum,默认值为1;使用 filter 设置想要的相册资源类型,包括 imagesFilter、videosFilter、livePhotosFilter,亦可以设置为数组@[ videoFilter , livePhotosFilter ]显示多种类型.
  2. 设置 PHPickerViewControllerDelegate 代理,接收选中照片后的回调;
  3. 在代理回调 piscker:didFinishPicking: 中处理返回结果 PHPickerResult;
  1. PHPicker 使用的独立的进程获取相册数据,所以不会影响App的性能,解决了之前自定义相册,图片吃内存的问题。

  2. 因为 PHPicker 使用的系统独立进程,当用户选中所选照片时,也只会回调相应照片的图片信息,所以不需要App申请权限,也不受新增的限制模式的影响。换句话说,如果只使用了 PHPicker ,则完成不需要在代码里面申请权限,info.plist 文件里面也不需要申请权限,直接使用即可。

  3. 支持多选。

  4. 支持按照 image,video,livePhotos 类型进行选择。

  5. 支持搜索,页面上有搜索框。

  1. 不支持选中图片的编辑,例如选中后裁剪成正方形,需要自定义实现了;
  2. 不能直接获取到 PHAsset ,如果想要获取,则需要获取用户权限,使用户授权。
- (void)showPhotoLibrary {
    UIViewController *topVC = [UIViewController lg_currentViewController];
    if (@available(iOS 14, *)) {
        PHPickerConfiguration *config = [[PHPickerConfiguration alloc] init];
        config.selectionLimit = 1;
        config.filter = [PHPickerFilter imagesFilter];
        PHPickerViewController *pickVC = [[PHPickerViewController alloc] initWithConfiguration:config];
        pickVC.delegate = self;
        [topVC presentViewController:pickVC animated:YES completion:nil];
    }
}


- (void)picker:(PHPickerViewController *)picker didFinishPicking:(NSArray<PHPickerResult *> *)results API_AVAILABLE(ios(14)) {
    if (results == nil || results.count <= 0) {
        [LGToastView showCenterWithTitle:@"选择照片失败" hideDelay:1.5];
    } else {
        PHPickerResult *result = [results firstObject];
        if ([result.itemProvider canLoadObjectOfClass:[UIImage class]]) {
            __weak __typeof(self)weakSelf = self;
            [result.itemProvider loadObjectOfClass:[UIImage class] completionHandler:^(__kindof id<NSItemProviderReading>  _Nullable object, NSError * _Nullable error) {
                if (!error) {
                    UIImage *tmpImage = (UIImage *)object;
                    !weakSelf.chooseImageComplete ?: weakSelf.chooseImageComplete(tmpImage);
                } else {
                    [LGToastView showCenterWithTitle:@"选择照片失败" hideDelay:1.5];
                }
            }];
        } else {
            [LGToastView showCenterWithTitle:@"选择照片失败" hideDelay:1.5];
        }
    }
    [picker dismissViewControllerAnimated:YES completion:nil];
}

参考资料

WWDC视频: Meet the new Photos picker

上一篇 下一篇

猜你喜欢

热点阅读