2018.01.18更新
近日遇到通过xcode的upload to AppStrore 上传成功后,在iTunes的MyApps中找不到构建的版本~,后面通过查询资料才知道。是因为申请对应权限时没有在value中填写对应内容引起的~~markmarkmark。蠢哭了
原文
由于苹果对于获取用户隐私权限的严格控制,在获取用户相机/相册/位置/通知等权限时,必须由用户手动授权之后方可获取。故事,就是在这样的场景下开始的...
一、权限设置
Q:获取对应权限需要做些什么?
A:需要在info.plist中预设对应权限key值,如下
Privacy - Camera Usage Description -> 相机
Privacy - Microphone Usage Description -> 麦克风
Privacy - Photo Library Usage Description -> 读取相册
Privacy - Photo Library Additions Usage Description -> 保存图片至相册
Privacy - NSLocationAlwaysUsageDescription -> 始终获取地理位置
Privacy - NSLocationWhenInUseUsageDescription -> 使用时获取地理位置
PS:位置授权二选一即可
在使用对应功能如调起相册时系统会弹框要求用户授权。
二、授权状态检测
Q:如果用户没有同意授权或拒绝授权,如何保证在使用相关功能时提示用户开启权限?
A:需要检测对应权限状态,
如果用户未授权---->提示用户授权(系统行为)
如果用户之前拒绝授权---->提示用户开启授权(App实现)
如下
检测麦克风权限<支持7.0+>
+(BOOL)detectionMediaState:(void(^)())authorizedBlock
{
BOOL isAvalible = NO;
NSString *mediaType = AVMediaTypeAudio;
AVAuthorizationStatus authStatus = [AVCaptureDevice authorizationStatusForMediaType:mediaType];
//用户尚未授权->申请权限
if (authStatus == AVAuthorizationStatusNotDetermined)
{
[AVCaptureDevice requestAccessForMediaType:mediaType completionHandler:^(BOOL granted) {
if(granted)
{
if (authorizedBlock)
{
authorizedBlock();
}
}}];
}
//用户已经授权
else if (authStatus == AVAuthorizationStatusAuthorized)
{
isAvalible = YES;
if (authorizedBlock)
{
authorizedBlock();
}
}
//用户拒绝授权
else
{
//提示用户开启麦克风权限
[SystemManager openSettingPagewithMessage:@"麦克风"];
}
return isAvalible;
}
相册访问权限<支持7.0+>
+(BOOL)detectionPhotoState:(void(^)())authorizedBlock
{
BOOL isAvalible = NO;
if (iOS8OrLater)
{
PHAuthorizationStatus authStatus = [PHPhotoLibrary authorizationStatus];
//用户尚未授权
if (authStatus == PHAuthorizationStatusNotDetermined)
{
[PHPhotoLibrary requestAuthorization:^(PHAuthorizationStatus status) {
if (status == PHAuthorizationStatusAuthorized)
{
if (authorizedBlock)
{
authorizedBlock();
}
}}];
}
//用户已经授权
else if (authStatus == PHAuthorizationStatusAuthorized)
{
isAvalible = YES;
if (authorizedBlock)
{
authorizedBlock();
}
}
//用户拒绝授权
else
{
//提示用户开启相册权限
[SystemManager openSettingPagewithMessage:@"照片"];
}
}
else
{
ALAuthorizationStatus authStatus = [ALAssetsLibrary authorizationStatus];
//用户已经授权
if (authStatus == ALAuthorizationStatusAuthorized)
{
isAvalible = YES;
if (authorizedBlock)
{
authorizedBlock();
}
}
//用户拒绝授权
else
{
//提示用户开启相册权限
[SystemManager openSettingPagewithMessage:@"照片"];
}
}
return isAvalible;
}
相机访问权限<支持7.0+>
+(BOOL)detectionCameraState:(void(^)())authorizedBlock
{
BOOL isAvalible = NO;
AVAuthorizationStatus authStatus = [AVCaptureDevice authorizationStatusForMediaType:AVMediaTypeVideo];
//用户尚未授权
if (authStatus == AVAuthorizationStatusNotDetermined)
{
[AVCaptureDevice requestAccessForMediaType:AVMediaTypeVideo completionHandler:^(BOOL granted) {
if (granted)
{
if (authorizedBlock)
{
authorizedBlock();
}
}
}];
}
//用户已经授权
else if (authStatus == AVAuthorizationStatusAuthorized)
{
isAvalible = YES;
if (authorizedBlock)
{
authorizedBlock();
}
}
//用户拒绝授权
else
{
//提示用户开启相机权限
[SystemManager openSettingPagewithMessage:@"相机"];
}
return isAvalible;
}
通知权限<支持8.0+>
+(BOOL)detectionNotificationState:(void(^)())authorizedBlock
{
BOOL isAvalible = NO;
if (iOS8OrLater)
{
//用户拒绝授权
if ([UIApplication sharedApplication].currentUserNotificationSettings.types == UIUserNotificationTypeNone)
{
isAvalible = NO;
//提示用户开启通知权限
[SystemManager openSettingPagewithMessage:@"通知"];
}
else
{
isAvalible = YES;
}
}
return isAvalible;
}
定位权限<支持8.0+>
+(BOOL)detectionLocationState:(void(^)())authorizedBlock
{
BOOL isAvalible = NO;
CLAuthorizationStatus authStatus = [CLLocationManager authorizationStatus];
if (iOS8OrLater)
{
//用户尚未授权
if (authStatus == kCLAuthorizationStatusNotDetermined)
{
//检测位置服务是否可用
if([CLLocationManager locationServicesEnabled])
{
if(!_locationManager)
{
_locationManager = [[CLLocationManager alloc] init];
if([_locationManager respondsToSelector:@selector(requestWhenInUseAuthorization)])
{
[_locationManager requestWhenInUseAuthorization];
}
//设置代理
[_locationManager setDelegate:self];
//设置定位精度
[_locationManager setDesiredAccuracy:kCLLocationAccuracyBest];
//设置距离筛选
[_locationManager setDistanceFilter:100];
[_locationManager startUpdatingHeading];
}
else
{
//开始定位
[_locationManager startUpdatingLocation];
}
}
else
{
//提示用户打开定位权限
[SystemManager openSettingPagewithMessage:@"定位"];
}
}
//用户已经授权
else if (authStatus == kCLAuthorizationStatusAuthorizedAlways||authStatus == kCLAuthorizationStatusAuthorizedWhenInUse)
{
isAvalible = YES;
if (authorizedBlock)
{
authorizedBlock();
}
}
//用户决绝授权
else
{
//提示用户打开定位权限
[SystemManager openSettingPagewithMessage:@"定位"];
}
}
return isAvalible;
}
三、设置页面跳转
Q:提示用户需要打开对应权限,能否可以直接跳转到对应开关页面?
A:iOS8之后是可以的
跳转到设置界面
+(void)openSettingPagewithMessage:(NSString *)message
{
if (iOS8OrLater)
{
[[SystemManager shareManager] showSystemAlertwithTitle:@"提示" message:[NSString stringWithFormat:@"为了更好的体验功能,请到设置页面->隐私->%@,将XX对应开关开启",message] cancelButtonTitle:@"下次提醒" otherButtonTitles:@"去设置" baseController:nil resultBlock:^(NSInteger index) {
if (index == 1)
{
NSURL *url = [NSURL URLWithString:UIApplicationOpenSettingsURLString];
if ([[UIApplication sharedApplication] canOpenURL:url])
{
[[UIApplication sharedApplication] openURL:url];
}
}
}];
}
//iOS8以下
else
{
[[SystemManager shareManager] showSystemAlertwithTitle:@"提示" message:[NSString stringWithFormat:@"为了更好的体验功能,请到设置页面->隐私->%@,将XX对应开关开启",message] cancelButtonTitle:@"我知道了" otherButtonTitles:nil baseController:nil resultBlock:nil];
}
}
XX为App的名字
四、结束语
谢谢大家。