iOS权限问题

Posted CH520 -- Cnblogs。

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了iOS权限问题相关的知识,希望对你有一定的参考价值。

1、简介

  • ios中经常会遇到访问相册、相机、麦克疯、蓝牙、以及推送等权限,所以每次我们要使用这些权限是都要记得查看用户是否允许了,如果用户禁止了你的访问权限,你仍然去调取相册或者相机等,那么就会先出现下面的这个提示。而且是英文的,这时候用户可能有些懵逼了,这个时候我们最好给一个提示,用户点击确定后,我们最好贴心的跳转到应用的权限出,让用户一键允许。
  • 注意:iOS10 中需要在plist文件中添加获取权限声明,否则会崩溃,提示信息如下:
    [access] This app has crashed because it attempted to access privacy-sensitive data without a usage description. The app\'s Info.plist must contain an NSMicrophoneUsageDescription key with a string value explaining to the user how the app uses this data.
    plist中的设置如下图

2、相册权限

  • 2.1 检测照片权限

    typedef NS_ENUM(NSInteger, PHAuthorizationStatus) {
    	PHAuthorizationStatusNotDetermined = 0,  // 用户尚未做出选择这个应用程序的问候
    	PHAuthorizationStatusRestricted,         // 此应用程序没有被授权访问的照片数据。可能是家长控制权限
    	PHAuthorizationStatusDenied,             // 用户已经明确否认了权限的访问
    	PHAuthorizationStatusAuthorized          // 用户已经授权应用访问照片数据
    } PHOTOS_AVAILABLE_IOS_TVOS(8_0, 10_0);
    
    导入头文件#import<Photos/Photos.h>
    
    // 检查照片权限
    - (void) checkPhotoStauts {
    	PHAuthorizationStatus photoAuthorStatus = [phphotoLibrary authorizationStatus];
    
    	switch (photoAuthorStatus) {
    		case PHAuthorizationStatusAuthorized:
    			self.photoLibraryStatus = @"PHAuthorizationStatusAuthorized";
    			break;
    		case PHAuthorizationStatusDenied:
    			self.photoLibraryStatus = @"PHAuthorizationStatusDenied";
    			break;
    		case PHAuthorizationStatusNotDetermined:
    			self.photoLibraryStatus = @"PHAuthorizationStatusNotDetermined";
    			break;
    		case PHAuthorizationStatusRestricted:
    			self.photoLibraryStatus = @"PHAuthorizationStatusRestricted";
    			break;
    		default:
    			break;
    	}
    }
    
  • 2.2 获取照片权限

    // 授权照片
    - (void)phontLibraryAction{
    	[PHPhotoLibrary requestAuthorization:^(PHAuthorizationStatus status) {
    
    	}];
    }
    

3、相机权限

  • 3.1 检测相机权限

    typedef NS_ENUM(NSInteger, AVAuthorizationStatus) {
    	AVAuthorizationStatusNotDetermined = 0,    // 请问是否授权访问
    	AVAuthorizationStatusRestricted,           // 权限都限制
    	AVAuthorizationStatusDenied,               // 拒绝访问
    	AVAuthorizationStatusAuthorized            // 授权访问
    } NS_AVAILABLE_IOS(7_0) __TVOS_PROHIBITED;
    
    - (void) checkVideoStatus {
    
    	AVAuthorizationStatus authStatus = [AVCaptureDevice authorizationStatusForMediaType:AVMediaTypeVideo];
    
    	switch (authStatus) {
    		case AVAuthorizationStatusNotDetermined:
    			// 没有询问是否开启相机
    			self.videoStatus = @"AVAuthorizationStatusNotDetermined";
    			break;
    		case AVAuthorizationStatusRestricted:
    			// 未授权,家长限制
    			self.videoStatus = @"AVAuthorizationStatusRestricted";
    			break;
    		case AVAuthorizationStatusDenied:
    			// 未授权
    			self.videoStatus = @"AVAuthorizationStatusDenied";
    			break;
    		case AVAuthorizationStatusAuthorized:
    			// 玩家授权
    			self.videoStatus = @"AVAuthorizationStatusAuthorized";
    			break;
    		default:
    			break;
    	}
    }
    
  • 3.2 获取相机权限

    // 授权相机
    - (void)videoAuthAction {
    	[AVCaptureDevice requestAccessForMediaType:AVMediaTypeVideo completionHandler:^(BOOL granted) {
    		NSLog(@"%@",granted ? @"相机准许":@"相机不准许");
    	}];
    }
    

4、蓝牙权限

  • 4.1 判断是否打开了蓝牙

    • 其实在我们使用蓝牙的时候即创建时就需要遵循CBCentralManagerDelegate这个代理,他有一个代理方法是不停的监控蓝牙状态的变化。
    - (void)centralManagerDidUpdateState:(CBCentralManager *)central {
    	switch (central.state) {
    		case CBManagerStateUnknown:
    			{
    			// 初始的时候是未知的(刚刚创建的时候)
    			}
    			break;
    		case CBManagerStateResetting:
    			{
    			// 正在重置状态
    			}
    			break;
    		case CBManagerStateUnsupported:
    			{
    			// 设备不支持的状态
    			}
    			break;
    		case CBManagerStateUnauthorized:
    			{
    			[stringForCentral appendString:@"Resetting\\n"];
    			// 设备未授权状态
    			}
    			break;
    		case CBManagerStatePoweredOff:
    			{
    			//设备关闭状态
    			}
    			break;
    		case CBManagerStatePoweredOn:
    			{
    			// 设备开启状态 -- 可用状态
    			}
    			break;
    		default:
    			{
    
    			}
    			break;
    		}
    	}
    }
    
  • 4.2 获取蓝牙权限

    • 我们可以在不同的状态下做一些事情。当然我们也可以通过CBCentralManager的state方法获取蓝牙的链接状态,还有就是我们创建CBCentralManager系统如果发现蓝牙没有开启会自动弹出一个窗口可以去设置里面打开蓝牙。
    • 当然如果我们想自己给一个用户提示然后跳转到设置页面也是可以的,iOS10以后打开方式有些区别
    NSString *urlString = @"App-Prefs:root=Bluetooth";
    if ([[UIApplication sharedApplication] canOpenURL:[NSURL URLWithString:urlString]]) {
    
    	if (IOS_VERSION>10.0) {
    		[[UIApplication sharedApplication] openURL:[NSURL URLWithString:urlString] options:@{} completionHandler:nil];
    	} 
    	else {
    		[[UIApplication sharedApplication] openURL:[NSURL URLWithString:urlString]];
    	}
    }
    

5、推送权限

  • 5.1 判断用户是否允许推送

    • 其中iOS8以上与iOS8以下有些区别,所以需要进行iOS版本判断。
    #define IOS8 ([[[UIDevice currentDevice] systemVersion] doubleValue] >=8.0 ? YES : NO)
    
    if (IOS8) { // iOS8以上包含iOS8
    	if ([[UIApplication sharedApplication] currentUserNotificationSettings].types  ==UIUserNotificationTypeNone) {
    		NSLog(@"没有开启");
    	}
    } 
    else { // ios7 以下
    	if ([[UIApplication sharedApplication] enabledRemoteNotificationTypes]  == UIRemoteNotificationTypeNone) {
    		NSLog(@"没有开启");
    	}
    }
    typedef NS_OPTIONS(NSUInteger, UIUserNotificationType) {
    	UIUserNotificationTypeNone   = 0,      // 用户禁止了推送
    	UIUserNotificationTypeBadge  = 1 << 0, // 用户开启了推送角标
    	UIUserNotificationTypeSound  = 1 << 1, // 用户开启了推送提示音
    	UIUserNotificationTypeAlert  = 1 << 2, // 用户开启了通知栏提醒
    } NS_ENUM_DEPRECATED_IOS(8_0, 10_0, "Use UserNotifications Framework\'s UNAuthorizationOptions") __TVOS_PROHIBITED;
    

6、位置服务权限

  • 6.1 判断位置服务是否被禁用

    if([CLLocationManager locationServicesEnabled] && [CLLocationManager authorizationStatus] == kCLAuthorizationStatusDenied) {
    	NSLog(@"没打开");
    }
    locationServicesEnabled这个返回的结果是否设置过位置服务,大概是这个意思,我们第一次访问位置是,系统会给用户一个提示,是否允许app使用位置信息。如果你选择了是或者否,这个值就是YES,kCLAuthorizationStatusDenied代表用户明确拒绝了访问位置信息。
    typedef NS_ENUM(int, CLAuthorizationStatus) {
    kCLAuthorizationStatusNotDetermined = 0, // 定位服务授权状态是用户没有决定是否使用定位服务。
    kCLAuthorizationStatusRestricted,        // 定位服务授权状态是受限制的。可能是由于活动限制定位服务,用户不能改变。这个状态可能不是用户拒绝的定位服务。
    kCLAuthorizationStatusDenied,            // 定位服务授权状态已经被用户明确禁止,或者在设置里的定位服务中关闭。
    kCLAuthorizationStatusAuthorizedAlways NS_ENUM_AVAILABLE(10_12, 8_0),// 定位服务授权状态已经被用户允许在任何状态下获取位置信息。包括监测区域、访问区域、或者在有显著的位置变化的时候。
    kCLAuthorizationStatusAuthorizedWhenInUse NS_ENUM_AVAILABLE(NA, 8_0),//定位服务授权状态仅被允许在使用应用程序的时候。
    kCLAuthorizationStatusAuthorized NS_ENUM_DEPRECATED(10_6, NA, 2_0, 8_0, "Use kCLAuthorizationStatusAuthorizedAlways") __TVOS_PROHIBITED __WATCHOS_PROHIBITED = kCLAuthorizationStatusAuthorizedAlways // 这个枚举值已经被废弃了。他相当于kCLAuthorizationStatusAuthorizedAlways这个值。
    };
    
  • 6.2 跳转到设置页面,让用户设置权限

    • 如果我们需要跳转到设置位置让用户允许权限的方法是
    NSURL * url = [NSURL URLWithString:UIApplicationOpenSettingsURLString];
    if ([[UIApplication sharedApplication] canOpenURL:url]) {
    	if (IOS_VERSION>10.0) {
    		[[UIApplication sharedApplication] openURL:url options:@{} completionHandler:nil];
    	} 
    	else {
    		
    		[[UIApplication sharedApplication] openURL:url];
    	}
    }
    

7、麦克风权限

  • 7.1 检测麦克风权限

    // 检查麦克风权限
    - (void) checkAudioStatus {
    
    AVAuthorizationStatus authStatus = [AVCaptureDevice authorizationStatusForMediaType:AVMediaTypeAudio];
    
    switch (authStatus) {
    	case AVAuthorizationStatusNotDetermined:
    		// 没有询问是否开启麦克风
    		self.audioStatus = @"AVAuthorizationStatusNotDetermined";
    		break;
    	case AVAuthorizationStatusRestricted:
    		// 未授权,家长限制
    		self.audioStatus = @"AVAuthorizationStatusRestricted";
    		break;
    	case AVAuthorizationStatusDenied:
    		// 玩家未授权
    		self.audioStatus = @"AVAuthorizationStatusDenied";
    		break;
    	case AVAuthorizationStatusAuthorized:
    		// 玩家授权
    		self.audioStatus = @"AVAuthorizationStatusAuthorized";
    		break;
    	default:
    		break;
    	}
    }
    
  • 7.2 获取麦克风权限

    [AVCaptureDevice requestAccessForMediaType:AVMediaTypeAudio completionHandler:^(BOOL granted) {
    	NSLog(@"%@",granted ? @"麦克风准许":@"麦克风不准许");
    }];
    

以上是关于iOS权限问题的主要内容,如果未能解决你的问题,请参考以下文章

IOS开发-OC学习-常用功能代码片段整理

片段中的请求权限

iOS xcode 代码片段

如何使用 Swift 使用此代码片段为 iOS 应用程序初始化 SDK?

iOS常用于显示几小时前/几天前/几月前/几年前的代码片段

片段中的请求权限不显示对话框