iOS14 limited 相册权限和PHPickerConfi
2020-11-27 本文已影响0人
tuesone
获取相册权限
iOS14相册整理包含 plist设置,iOS相册权限查询和调取处理(兼容iOS14使用PHPickerViewController),以及PHAuthorizationStatusLimited权限处理。
plist 设置
// NSPhotoLibraryAddUsageDescription 用户存入相册时的提示信息。
// NSPhotoLibraryUsageDescription 相册访问权限信息,必须有此项,不然访问相册的时候 APP 会 Crash。
// PHPhotoLibraryPreventAutomaticLimited 如果未适配,App在每次冷启动时都会触发询问用户是否需要修改照片权限,添加可供App访问的图片。
iOS14 权限查询
if (@available(iOS 14, *)) {
PHAccessLevel level = PHAccessLevelReadWrite;
PHAuthorizationStatus status = [PHPhotoLibrary authorizationStatusForAccessLevel:level];
switch (status) {
case PHAuthorizationStatusLimited:
NSLog(@"limited");
//权限处理逻辑看下方
//这里可以直接调取从新选择图片,也可以直接调取 [self limtShow];
//建议每次启动后做一次选择图片处理 在调用[self limtShow]展示
break;
case PHAuthorizationStatusDenied:{
NSLog(@"denied");
UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:@"相机权限申请" message:@"没有权限访问您的相机,您可以进入系统“设置>隐私>相机”,允许访问您的相机" delegate:nil cancelButtonTitle:@"知道了" otherButtonTitles:nil];
[alertView show];
}
break;
case PHAuthorizationStatusAuthorized:
NSLog(@"authorized");
[self takeimagePhoto];
break;
case PHAuthorizationStatusNotDetermined:
NSLog(@"denied");
[self requestAuthorization];
break;
default:
break;
}
} else {
//判断相册权限
PHAuthorizationStatus photoAuthorStatus = [PHPhotoLibrary authorizationStatus];
if (photoAuthorStatus ==PHAuthorizationStatusAuthorized ) {
[self takeimagePhoto];
}else{
[self requestAuthorization];
}
}
请求权限
-(void)requestAuthorization{
if (@available(iOS 14, *)) {
PHAccessLevel level = PHAccessLevelReadWrite;
// 请求权限,需注意 limited 权限尽在 accessLevel 为 readAndWrite 时生效
[PHPhotoLibrary requestAuthorizationForAccessLevel:level handler:^(PHAuthorizationStatus status) {
switch (status) {
case PHAuthorizationStatusLimited:
NSLog(@"limited");
// [self takeimagePhoto];
[self limtShow];
// dispatch_async(dispatch_get_main_queue(), ^{
//
// [[PHPhotoLibrary sharedPhotoLibrary] presentLimitedLibraryPickerFromViewController:[AppUtily currentViewController]];
// });
break;
case PHAuthorizationStatusDenied:
NSLog(@"denied");
[self performSelectorOnMainThread:@selector(doAlert) withObject:nil waitUntilDone:YES];
break;
case PHAuthorizationStatusAuthorized:
NSLog(@"authorized");
[self takeimagePhoto];
break;
default:
break;
}
}];
} else {
//获取相册访问权限 ios8之后推荐用这种方法 //该方法提示用户授权对相册的访问
[PHPhotoLibrary requestAuthorization:^(PHAuthorizationStatus status) {
if (status == PHAuthorizationStatusDenied) {
NSLog(@"用户拒绝当前应用访问相册,我们需要提醒用户打开访问开关");
[self performSelectorOnMainThread:@selector(doAlert) withObject:nil waitUntilDone:YES];
}else if (status == PHAuthorizationStatusAuthorized){
//有权限 可直接跳转
[self takeimagePhoto];
}
}];
}
}
调取相册
-(void)takeimagePhoto{
dispatch_async(dispatch_get_main_queue(), ^{
if (@available(iOS 14.0, *)) {
PHPickerConfiguration *configuration = [[PHPickerConfiguration alloc] init];
configuration.filter = [PHPickerFilter imagesFilter]; // 可配置查询用户相册中文件的类型,支持三种
configuration.selectionLimit = 1; // 默认为1,为0时表示可多选。
PHPickerViewController *picker = [[PHPickerViewController alloc] initWithConfiguration:configuration];
picker.delegate = self;
// picker.editing = YES;//allowsEditing
picker.modalPresentationStyle = UIModalPresentationFullScreen;
picker.view.backgroundColor = [UIColor whiteColor];//注意需要进行暗黑模式适配
_picker = picker;
// picker vc,在选完图片后需要在回调中手动 dismiss
// [AppUtily currentViewController] 替换成self
[[AppUtily currentViewController] presentViewController:_picker animated:YES completion:^{
}];
//
//
} else {
UIImagePickerController* ipc = [[UIImagePickerController alloc] init];
ipc.navigationBar.translucent = NO;
if([UIImagePickerController isSourceTypeAvailable:UIImagePickerControllerSourceTypePhotoLibrary]) {
NSString *requiredMediaType = ( NSString *)kUTTypeImage;
NSArray *arrMediaTypes=[NSArray arrayWithObjects:requiredMediaType,nil];
[ipc setMediaTypes:arrMediaTypes];
ipc.sourceType = UIImagePickerControllerSourceTypePhotoLibrary;
//pickerImage.sourceType = UIImagePickerControllerSourceTypeSavedPhotosAlbum;
//ipc.mediaTypes = [UIImagePickerController availableMediaTypesForSourceType:ipc.sourceType];
}
// usePhotoImg = YES;
ipc.delegate = self;
ipc.allowsEditing = YES;
ipc.modalPresentationStyle = UIModalPresentationFullScreen;
if (@available(iOS 11, *)) {
UIScrollView.appearance.contentInsetAdjustmentBehavior = UIScrollViewContentInsetAdjustmentAutomatic;
}
// [AppUtily currentViewController] 替换成self
[[AppUtily currentViewController] presentViewController:ipc animated:YES completion:nil];
}
});
}
相册完成回调
- (void)picker:(PHPickerViewController *)picker didFinishPicking:(NSArray<PHPickerResult *> *)results API_AVAILABLE(ios(14));{
//结果为空直接返回
if (!results || !results.count) {
[picker dismissViewControllerAnimated:YES completion:nil];
return;
}
NSItemProvider *itemProvider = results.firstObject.itemProvider;
if ([itemProvider canLoadObjectOfClass:UIImage.class]) {
__weak typeof(self) weakSelf = self;
[itemProvider loadObjectOfClass:UIImage.class completionHandler:^(__kindof id<NSItemProviderReading> _Nullable object, NSError * _Nullable error) {
if ([object isKindOfClass:UIImage.class]) {
__strong typeof(self) strongSelf = weakSelf;
dispatch_async(dispatch_get_main_queue(), ^{
UIImage *image = (UIImage *)object;
//处理获取的image
if ([strongSelf.delegate respondsToSelector:@selector(TZAlreadyLoginViewDelegateWithActionEnum:withdata:)]) {
[strongSelf.delegate TZAlreadyLoginViewDelegateWithActionEnum:ActionEnumChangeTitleImage withdata:image];
}
[picker dismissViewControllerAnimated:YES completion:nil];
});
}
}];
}
}
iOS14以下UIImagePickerController
#pragma mark UIImagePickerControllerDelegate
- (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info{
UIImage *image = [info objectForKey:UIImagePickerControllerEditedImage];
//处理获取的image
if ([self.delegate respondsToSelector:@selector(TZAlreadyLoginViewDelegateWithActionEnum:withdata:)]) {
[self.delegate TZAlreadyLoginViewDelegateWithActionEnum:ActionEnumChangeTitleImage withdata:image];
NSLog(@"tzdelegate---imagePickerController");
}
[picker dismissViewControllerAnimated:YES completion:nil];
}
- (void)navigationController:(UINavigationController *)navigationController didShowViewController:(UIViewController *)viewController animated:(BOOL)animated
{
if ([UIDevice currentDevice].systemVersion.floatValue < 11) {
return;
}
if ([viewController isKindOfClass:NSClassFromString(@"PUPhotoPickerHostViewController")]) {
[viewController.view.subviews enumerateObjectsUsingBlock:^(__kindof UIView * _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {
if (obj.frame.size.width < 42) {
[viewController.view sendSubviewToBack:obj];
*stop = YES;
}
}];
}
}
-(void)imagePickerController:(UIImagePickerController *)picker didFinishPickingImage:(UIImage *)image editingInfo:(NSDictionary *)editingInfo{
}
- (void)imagePickerControllerDidCancel:(UIImagePickerController *)picker{
[picker dismissViewControllerAnimated:YES completion:nil];
if (@available(iOS 11, *)) {
UIScrollView.appearance.contentInsetAdjustmentBehavior = UIScrollViewContentInsetAdjustmentNever;
}
}
iOS14 PHAuthorizationStatusLimited 权限处理
-(void)limtShow{
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进行显示
NSMutableArray<PHAsset *> *assets = [NSMutableArray array];
[self.fetchList enumerateObjectsUsingBlock:^(id _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {
PHAsset *asset = (PHAsset *)obj;
NSLog(@"照片名%@", [asset valueForKey:@"filename"]);
[assets addObject:asset];
}];
NSString * numStr = [NSString stringWithFormat:@"全部图片(%ld)",assets.count];
self.array_collect = [NSMutableArray array];
NSLog(@"%@",numStr);
for (PHAsset *set in assets) {
PHImageRequestOptions *options = [[PHImageRequestOptions alloc] init];
options.deliveryMode = PHImageRequestOptionsDeliveryModeHighQualityFormat;
[[PHImageManager defaultManager] requestImageForAsset:set targetSize:[UIScreen mainScreen].bounds.size contentMode:PHImageContentModeAspectFit options:options resultHandler:^(UIImage *result, NSDictionary *info) {
//设置处理图片
[self.array_collect addObject:result];
[self.collection reloadData];
}];
NSLog(@"%lu",(unsigned long)_array_collect.count);
}
}
主动弹出选择照片PHPickerViewController
[[PHPhotoLibrary sharedPhotoLibrary] presentLimitedLibraryPickerFromViewController:self];
相册limt 选择照片后发生改变
加入协议 PHPhotoLibraryChangeObserver //<PHPhotoLibraryChangeObserver>
//在初始化时加入
[[PHPhotoLibrary sharedPhotoLibrary] registerChangeObserver:self];
//结束时加入
- (void)dealloc {
[[PHPhotoLibrary sharedPhotoLibrary] unregisterChangeObserver:self];
// NSLog(@"%@ dealloc",NSStringFromClass(self.class));
}
- (void)photoLibraryDidChange:(PHChange *)changeInstance;{
[self limtShow];
}