前言
苹果在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 只能选中一张图片已经不符合需求了,将逐渐被废弃替换。
- 使用PHPickerController
- 使用 PHPickerConfiguration 配置 PHPicker,键 selectionLimit 设置为 n 表示最多可选中 n 张图片,0 为 maximum,默认值为1;使用 filter 设置想要的相册资源类型,包括 imagesFilter、videosFilter、livePhotosFilter,亦可以设置为数组@[ videoFilter , livePhotosFilter ]显示多种类型.
- 设置 PHPickerViewControllerDelegate 代理,接收选中照片后的回调;
- 在代理回调 piscker:didFinishPicking: 中处理返回结果 PHPickerResult;
- PHPickerController的优点
-
PHPicker 使用的独立的进程获取相册数据,所以不会影响App的性能,解决了之前自定义相册,图片吃内存的问题。
-
因为 PHPicker 使用的系统独立进程,当用户选中所选照片时,也只会回调相应照片的图片信息,所以不需要App申请权限,也不受新增的限制模式的影响。换句话说,如果只使用了 PHPicker ,则完成不需要在代码里面申请权限,info.plist 文件里面也不需要申请权限,直接使用即可。
-
支持多选。
-
支持按照 image,video,livePhotos 类型进行选择。
-
支持搜索,页面上有搜索框。
- PHPickerController的缺点
- 不支持选中图片的编辑,例如选中后裁剪成正方形,需要自定义实现了;
- 不能直接获取到 PHAsset ,如果想要获取,则需要获取用户权限,使用户授权。
- PHPickerController 代码 Demo 演示
- (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];
}
网友评论