iOS 权限设置判断和跳转 - 最全最详细
Posted 长沙火山
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了iOS 权限设置判断和跳转 - 最全最详细相关的知识,希望对你有一定的参考价值。
一、权限设置
ios 10以后,苹果增强了对用户隐私的保护,访问照相机、相册、麦克风、定位、通讯录等,都需要在info.plist 文件中添加权限,而且少一个都不行。根据需要添加,项目中使用了什么,就添加对应的权限。
权限 | 字段 |
---|---|
相册使用权限 | Privacy - Photo Library Usage Description |
编辑相册权限 | Privacy - Photo Library Additions Usage Description |
相机权限 | Privacy - Camera Usage Description |
通讯录权限 | Privacy - Contacts Usage Description |
麦克风权限 | Privacy - Microphone Usage Description |
蓝牙权限 | Privacy - Bluetooth Peripheral Usage Description |
定位权限 | Privacy - Location Always Usage Description |
定位权限 | Privacy - Location Usage Description |
定位权限 | Privacy - Location When In Use Usage Description |
定位权限 | Privacy - Location Always and When In Use Usage Description |
媒体库权限 | Privacy - Media Library Usage Description |
日历权限 | Privacy - Calendars Usage Description |
提醒事项权限 | Privacy - Reminders Usage Description |
FaceID权限 | Privacy - Face ID Usage Description |
健康记录权限 | Privacy - Health Records Usage Description |
健康分享权限 | Privacy - Health Share Usage Description |
健康更新权限 | Privacy - Health Update Usage Description |
运动权限 | Privacy - Motion Usage Description |
音乐权限 | Privacy - Music Usage Description |
NFC权限 | Privacy - NFC Scan Usage Description |
Siri权限 | Privacy - Siri Usage Description |
语音识别权限 | Privacy - Speech Recognition Usage Description |
智能家具权限 | Privacy - HomeKit Usage Description |
电视供应商权限 | Privacy - TV Provider Usage Description |
视频用户账号使用权限 | Privacy - Video Subscriber Account Usage Description |
事例:
Privacy - Camera Usage Description
APP需要选择视频进行编辑,请允许访问您的相机
Privacy - Microphone Usage Description
APP需要选择视频进行编辑,请允许访问您的麦克风
Privacy - Photo Library Additions Usage Description
APP需要导出视频到相册,请允许访问您的相册
二、权限判断
在 APP 的开发中,有很多功能是需要用户授权了之后才能使用,这里将常用的权限判断做一下总结。
2.1 网络权限
@import CoreTelephony; //引入头文件
//应用启动后,检测应用中是否有联网权限
CTCellularData *cellularData = [[CTCellularData alloc]init];
cellularData.cellularDataRestrictionDidUpdateNotifier = ^(CTCellularDataRestrictedState state)
//获取联网状态
switch (state)
case kCTCellularDataRestricted:
NSLog(@"Restricrted");
break;
case kCTCellularDataNotRestricted:
NSLog(@"Not Restricted");
break;
case kCTCellularDataRestrictedStateUnknown:
NSLog(@"Unknown");
break;
default:
break;
;
;
//查询应用是否有联网功能
CTCellularData *cellularData = [[CTCellularData alloc]init];
CTCellularDataRestrictedState state = cellularData.restrictedState;
switch (state)
case kCTCellularDataRestricted:
NSLog(@"Restricrted");
break;
case kCTCellularDataNotRestricted:
NSLog(@"Not Restricted");
break;
case kCTCellularDataRestrictedStateUnknown:
NSLog(@"Unknown");
break;
default:
break;
2.2 相册权限( iOS 8.0以上)
@import Photos; 导入头文件
//检查是否有相册权限
PHAuthorizationStatus photoAuthorStatus = [phphotoLibrary authorizationStatus];
switch (photoAuthorStatus)
case PHAuthorizationStatusAuthorized:
NSLog(@"Authorized");
break;
case PHAuthorizationStatusDenied:
NSLog(@"Denied");
break;
case PHAuthorizationStatusNotDetermined:
NSLog(@"not Determined");
break;
case PHAuthorizationStatusRestricted:
NSLog(@"Restricted");
break;
default:
break;
//获取相册权限
[PHPhotoLibrary requestAuthorization:^(PHAuthorizationStatus status)
if (status == PHAuthorizationStatusAuthorized)
NSLog(@"Authorized");
else
NSLog(@"Denied or Restricted");
];
2.3 相机和麦克风权限
@import AVFoundation; //导入头文件
//检查是否有相机或麦克风权限
//相机权限
AVAuthorizationStatus AVstatus = [AVCaptureDevice authorizationStatusForMediaType:AVMediaTypeVideo];
//麦克风权限
AVAuthorizationStatus AVstatus = [AVCaptureDevice authorizationStatusForMediaType:AVMediaTypeAudio];
switch (AVstatus)
case AVAuthorizationStatusAuthorized:
NSLog(@"Authorized");
break;
case AVAuthorizationStatusDenied:
NSLog(@"Denied");
break;
case AVAuthorizationStatusNotDetermined:
NSLog(@"not Determined");
break;
case AVAuthorizationStatusRestricted:
NSLog(@"Restricted");
break;
default:
break;
//获取相机或麦克风权限
//相机权限
[AVCaptureDevice requestAccessForMediaType:AVMediaTypeVideo completionHandler:^(BOOL granted)
if (granted)
NSLog(@"Authorized");
else
NSLog(@"Denied or Restricted");
];
//麦克风权限
[AVCaptureDevice requestAccessForMediaType:AVMediaTypeAudio completionHandler:^(BOOL granted)
if (granted)
NSLog(@"Authorized");
else
NSLog(@"Denied or Restricted");
];
2.4 定位权限
@import CoreLocation; //导入头文件
//检查定位功能是否可用
BOOL isLocation = [CLLocationManager locationServicesEnabled];
if (!isLocation)
NSLog(@"not turn on the location");
//检查定位权限
CLAuthorizationStatus CLstatus = [CLLocationManager authorizationStatus];
switch (CLstatus)
case kCLAuthorizationStatusAuthorizedAlways:
NSLog(@"Always Authorized");
break;
case kCLAuthorizationStatusAuthorizedWhenInUse:
NSLog(@"AuthorizedWhenInUse");
break;
case kCLAuthorizationStatusDenied:
NSLog(@"Denied");
break;
case kCLAuthorizationStatusNotDetermined:
NSLog(@"not Determined");
break;
case kCLAuthorizationStatusRestricted:
NSLog(@"Restricted");
break;
default:
break;
获取定位权限
CLLocationManager *manager = [[CLLocationManager alloc] init];
//一直获取定位信息
[manager requestAlwaysAuthorization];
//使用的时候获取定位信息
[manager requestWhenInUseAuthorization];
//在代理方法中查看权限是否改变
- (void)locationManager:(CLLocationManager *)manager didChangeAuthorizationStatus:(CLAuthorizationStatus)status
switch (status)
case kCLAuthorizationStatusAuthorizedAlways:
NSLog(@"Always Authorized");
break;
case kCLAuthorizationStatusAuthorizedWhenInUse:
NSLog(@"AuthorizedWhenInUse");
break;
case kCLAuthorizationStatusDenied:
NSLog(@"Denied");
break;
case kCLAuthorizationStatusNotDetermined:
NSLog(@"not Determined");
break;
case kCLAuthorizationStatusRestricted:
NSLog(@"Restricted");
break;
default:
break;
2.5 推送权限
//检查是否有推送权限
UIUserNotificationSettings *settings = [[UIApplication sharedApplication] currentUserNotificationSettings];
switch (settings.types)
case UIUserNotificationTypeNone:
NSLog(@"None");
break;
case UIUserNotificationTypeAlert:
NSLog(@"Alert Notification");
break;
case UIUserNotificationTypeBadge:
NSLog(@"Badge Notification");
break;
case UIUserNotificationTypeSound:
NSLog(@"sound Notification'");
break;
default:
break;
//获取推送权限
UIUserNotificationSettings *setting = [UIUserNotificationSettings settingsForTypes:UIUserNotificationTypeSound | UIUserNotificationTypeAlert | UIUserNotificationTypeBadge categories:nil];
[[UIApplication sharedApplication] registerUserNotificationSettings:setting];
2.6 通讯录权限 (iOS9.0及以后)
@import Contacts; //导入头文件
//检查是否有通讯录权限
CNAuthorizationStatus status = [CNContactStore authorizationStatusForEntityType:CNEntityTypeContacts];
switch (status)
case CNAuthorizationStatusAuthorized:
NSLog(@"Authorized:");
break;
case CNAuthorizationStatusDenied:
NSLog(@"Denied");
break;
case CNAuthorizationStatusRestricted:
NSLog(@"Restricted");
break;
case CNAuthorizationStatusNotDetermined:
NSLog(@"NotDetermined");
break;
//获取通讯录权限
CNContactStore *contactStore = [[CNContactStore alloc] init];
[contactStore requestAccessForEntityType:CNEntityTypeContacts completionHandler:^(BOOL granted, NSError * _Nullable error)
if (granted)
NSLog(@"Authorized");
else
NSLog(@"Denied or Restricted");
];
2.7 日历、备忘录权限
@import EventKit; //导入头文件
typedef NS_ENUM(NSUInteger, EKEntityType)
EKEntityTypeEvent, //日历
EKEntityTypeReminder //备忘
;
//检查是否有日历或者备忘录权限
EKAuthorizationStatus EKstatus = [EKEventStore authorizationStatusForEntityType:EKEntityTypeEvent];
switch (EKstatus)
case EKAuthorizationStatusAuthorized:
NSLog(@"Authorized");
break;
case EKAuthorizationStatusDenied:
NSLog(@"Denied'");
break;
case EKAuthorizationStatusNotDetermined:
NSLog(@"not Determined");
break;
case EKAuthorizationStatusRestricted:
NSLog(@"Restricted");
break;
default:
break;
//获取日历或备忘录权限
EKEventStore *store = [[EKEventStore alloc]init];
[store requestAccessToEntityType:EKEntityTypeEvent completion:^(BOOL granted, NSError * _Nullable error)
if (granted)
NSLog(@"Authorized");
else
NSLog(@"Denied or Restricted");
];
三、跳转到权限设置页面
在 APP 开发中,经常需要使用到一些权限,比如相机、定位、通知等,这些权限都需要用户授权之后,才能进行使用。一般的,当系统第一次需要用到这些功能时,系统会主动弹出授权提示框,询问用户是否同意 APP 使用该功能。如果用户选择了拒绝授权,那么用户就不能使用改功能。那么在用户拒绝授权之后,如何重新去授权使用该功能呢?通常有两种做法:
- 不做跳转,只弹出提示框,告知用户去 “设置 > 隐私 > 相机” 开启使用相机功能;
- 弹框提示,并跳转到设置的子界面;
方案一是苹果推荐的方法,因为苹果不建议开发者直接跳转到设置的子界面,并且苹果将跳转到设置子界面的一些 API 改成了私有的 API,所以方案二其实上架是有被拒的风险,但是从用户体验来讲,方案二显然更友好,所以开发者自己决定用哪种方案去实现吧,下面直接介绍方案二的实现代码。
// iOS 8.1 ~ iOS 14
- (void)pushSettingController
NSURL *url1 = [NSURL URLWithString:@"App-Prefs:root=NOTIFICATIONS_ID"];
NSURL *url2 = [NSURL URLWithString:UIApplicationOpenSettingsURLString];
if (@available(iOS 11.0, *))
if ([[UIApplication sharedApplication] canOpenURL:url2])
[[UIApplication sharedApplication] openURL:url2 options:@ completionHandler:nil];
else
if ([[UIApplication sharedApplication] canOpenURL:url1])
if (@available(iOS 10.0, *))
[[UIApplication sharedApplication] openURL:url1 options:@ completionHandler:nil];
else
[[UIApplication sharedApplication] openURL:url1];
附:设置页面对应的字符串
页面名称 | 对应字符串 |
---|---|
照片与相机 | App-Prefs:root=Photos |
隐私->麦克风 | App-Prefs:root=Privacy&path=MICROPHONE |
隐私->定位 | App-Prefs:root=Privacy&path=LOCATION |
隐私->相机 | App-Prefs:root=Privacy&path=CAMERA |
个人热点 | App-Prefs:root=INTERNET_TETHERING |
运营商 | App-Prefs:root=Carrier |
无线局域网 | App-Prefs:root=WIFI |
蜂窝移动网络 | App-Prefs:root=MOBILE_DATA_SETTINGS_ID |
蓝牙 | App-Prefs:root=Bluetooth |
通知 | App-Prefs:root=NOTIFICATIONS_ID |
页面名称 | 对应字符串 |
---|---|
通用 | App-Prefs:root=General |
通用-关于本机 | App-Prefs:root=General&path=About |
通用-键盘 | App-Prefs:root=General&path=Keyboard |
通用-辅助功能 | App-Prefs:root=General&path=ACCESSIBILITY |
通用-语言与地区 | App-Prefs:root=General&path=INTERNATIONAL |
通用-还原 | App-Prefs:root=Reset |
墙纸 | App-Prefs:root=Wallpaper |
Siri | App-Prefs:root=SIRI |
隐私 | App-Prefs:root=Privacy |
Safari | App-Prefs:root=SAFARI |
音乐 | App-Prefs:root=MUSIC |
音乐-均衡器 | App-Prefs:root=MUSIC&path=com.apple.Music:EQ |
FaceTime | App-Prefs:root=FACETIME |
四、打开任意APP设置页面
采用逆向开发的手段,通过Hook可以实现跳转到任意APP的设置页面。
#import <Foundation/Foundation.h>
@interface LSApplicationWorkspaceHook : NSObject
+ (instancetype)defaultWorkspace;
- (void)openURL:(NSURL *)url;
- (void)openWeChat;
@end
#import "LSApplicationWorkspaceHook.h"
@implementation LSApplicationWorkspaceHook
-(void)openWeChat
// 调用 LSApplicationWorkspace 的单例方法
Class aClass = NSClassFromString(@"LSApplicationWorkspace");
LSApplicationWorkspaceHook *hook = [aClass defaultWorkspace];
// 调用 LSApplicationWorkspace 的 `openURL:` 方法
[hook openURL:[NSURL URLWithString:@"app-prefs:com.tencent.xin"]];
@end
调用打开微信设置页面:
[[LSApplicationWorkspaceHook alloc] openWeChat];
以上是关于iOS 权限设置判断和跳转 - 最全最详细的主要内容,如果未能解决你的问题,请参考以下文章
Swift - 判断是否有某功能访问权限,没有则提示,并自动跳转到设置页