1、写在前面

  • APP开发避免不开系统权限的问题,如何在APP以更加友好的方式向用户展示系统权限,似乎也是开发过程中值得深思的一件事;
  • 那如何提高APP获取iOS系统权限的通过率呢?有以下几种方式:
    • 1.在用户打开APP时就向用户请求权限;
    • 2.告知用户授权权限后能够获得好处之后,再向用户请求权限;
    • 3.在绝对必要的情况下才向用户请求权限,例如:用户访问照片库时请求访问系统相册权限;
    • 4.在展示系统权限的对话框前,先向用户显示自定义的对话框,若用户选择不允许,默认无操作,若用户选择允许,再展示系统对话框。
  • 上述情况在开发过程中是经常遇到的,不同方式的选择会影响最后用户交互体验。

2、权限分类

  • 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 9.0之前
    • 导入头文件 #import <AssetsLibrary/AssetsLibrary.h>
    • 检查是否有相册权限
     ALAuthorizationStatus status = [ALAssetsLibrary authorizationStatus];
    switch (status) {
    case ALAuthorizationStatusAuthorized:
    NSLog(@"Authorized");
    break;
    case ALAuthorizationStatusDenied:
    NSLog(@"Denied");
    break;
    case ALAuthorizationStatusNotDetermined:
    NSLog(@"not Determined");
    break;
    case ALAuthorizationStatusRestricted:
    NSLog(@"Restricted");
    break; default:
    break;
    }
  • 相册权限--iOS 8.0之后

    • 导入头文件 #import <Photos/Photos.h>
    • 检查是否有相册权限
    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/AVFoundation.h>
    • 检查是否有相机或麦克风权限
    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/CoreLocation.h>
    • 由于iOS8.0之后定位方法的改变,需要在info.plist中进行配置;
    • 检查是否有定位权限
    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 <AddressBook/AddressBook.h>
    • 检查是否有通讯录权限
    ABAuthorizationStatus ABstatus = ABAddressBookGetAuthorizationStatus();
    switch (ABstatus) {
    case kABAuthorizationStatusAuthorized:
    NSLog(@"Authorized");
    break;
    case kABAuthorizationStatusDenied:
    NSLog(@"Denied'");
    break;
    case kABAuthorizationStatusNotDetermined:
    NSLog(@"not Determined");
    break;
    case kABAuthorizationStatusRestricted:
    NSLog(@"Restricted");
    break;
    default:
    break;
    }
    • 获取通讯录权限
    ABAddressBookRef addressBook = ABAddressBookCreateWithOptions(NULL, NULL);
    ABAddressBookRequestAccessWithCompletion(addressBook, ^(bool granted, CFErrorRef error) {
    if (granted) {
    NSLog(@"Authorized");
    CFRelease(addressBook);
    }
    else {
    NSLog(@"Denied or Restricted");
    }
    });
    • iOS9.0及以后
    • 导入头文件#import <Contacts/Contacts.h>
    • 检查是否有通讯录权限
    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 日历、备忘录权限

    • 导入头文件
    • 检查是否有日历或者备忘录权限
    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");
    }
    }];

3、最后一点

  • 所有获取权限的方法,多用于用户第一次操作应用,iOS 8.0之后,将这些设置都整合在一起,并且可以开启或关闭相应的权限。所有的权限都可以通过下面的方法打开:
[[UIApplication sharedApplication] openURL:[NSURL URLWithString:UIApplicationOpenSettingsURLString]];

iOS应用开发权限请求处理的更多相关文章

  1. iOS开发-iOS 10 由于权限问题导致崩溃的那些坑

     iOS开发-iOS 10 由于权限问题导致崩溃的那些坑 6月份的WWDC大会结束有一段时间了,相信很多开发者也是在努力工作的闲时用着Xcode8 Beta版学习着新的特性吧. 使用Xcode8写自己 ...

  2. iOS 10 开发问题总结

    兼容iOS 10 资料整理笔记   1.Notification(通知) 自从Notification被引入之后,苹果就不断的更新优化,但这些更新优化只是小打小闹,直至现在iOS 10开始真正的进行大 ...

  3. iOS蓝牙开发(二)蓝牙相关基础知识

    原文链接: http://liuyanwei.jumppo.com/2015/07/17/ios-BLE-1.html iOS蓝牙开发(一)蓝牙相关基础知识: 蓝牙常见名称和缩写 MFI ====== ...

  4. web前端开发与iOS终端开发的异同[转]

    * {-webkit-tap-highlight-color: rgba(0,0,0,0);}html {-webkit-text-size-adjust: none;}body {font-fami ...

  5. iOS蓝牙开发(4.0)详解

    最近由于项目需要, 一直在研究蓝牙4.0,在这儿分享给大家, 望共同进步. 一.关于蓝牙开发的一些重要的理论概念: 1.当前ios中开发蓝牙所运用的系统库是<CoreBluetooth/Core ...

  6. iOS 11开发教程(九)iOS11数据线连接真机测试

    iOS 11开发教程(九)iOS11数据线连接真机测试 在Xcode 7.0之后,苹果公司在开发许可权限上做了很多的改变,在测试App方面取消了一些限制.在Xcode7.0之前的版本,苹果公司只向注册 ...

  7. Web前端开发与iOS终端开发的异同

    语言 前端和终端作为面向用户端的程序,有个共同特点:需要依赖用户机器的运行环境,所以开发语言基本上是没有选择的,不像后台想用什么就用什么,iOS只能用Objective-C,前端只能javascrip ...

  8. iOS 蓝牙开发详解

    目前iOS智能硬件的开发交互方式主要分为两种,一种是基于低功耗的蓝牙4.0技术(由于耗电低,也称作为BLE(Bluetooth Low Energy))对应iOS的框架为CoreBluetooth,另 ...

  9. 中文 iOS/Mac 开发博客列表

    中文 iOS/Mac 开发博客列表 博客地址 RSS地址 OneV's Den http://onevcat.com/atom.xml 一只魔法师的工坊 http://blog.ibireme.com ...

随机推荐

  1. 打包jar文件并自动运行

    1,首先在eclipse 或MyEclipse 中测试通过,没有问题,(每次修改要update Maven) 2,修改pom.xml ---把build中改为<excludes> < ...

  2. Mysql合并两列数据

    实例: UPDATE x_yiyuanpinggu_nengli SET ch_yuzhongfangxiang = CONCAT(ch_yuanyuzhong,ch_mubiaoyuzhong) M ...

  3. 解决ecplise+phthon2.7中使用pytesser和tesseract进行ocr,出现报错的问题

    网上很多使用ecplise+phthon2.7中使用pytesser或者tesseract进行OCR网站验证码的案例,但配置起来实在让人崩溃. 通用步骤:1.下载了pytesser_v0.0.1: 2 ...

  4. Force SDK to create Appointment programmatically in crm 2013 onPremise

    As I know based on this: msdn.microsoft.com/.../gg334289.aspx and community.dynamics.com/.../book-an ...

  5. JAVA heap space 内存溢出

    3月28日开始使用JAVA调用SAP RFC后提示内存溢出 尝试增加set java_OPTS.....但仍然提示内存溢出 最终设置方法

  6. java基于feemarker 生成word文档(超级简单)

    问题由来: 开发个新需求,需要按规定导出word文档,文档截图如下 因为之前没做过这个,一脸懵B啊,导出excel和txt倒是经常接触到,对于这个word这种格式不严谨的文件怎么处理呢? 技术选型:可 ...

  7. Unity Remote 5 使用

    从哪里下载,我是从应用商店里下载的 一. Android版 首先应该确保安装了最新的 Android SDK(这对于在设备上设置端口转发非常必要). 然后,使用 USB 连接线连接设备与电脑,并启动U ...

  8. SQL Server 2008 收缩日志

    如果SQL SERVER 日志过大,比如,达到了几十个G,想一次性收缩的,直接执行下面命令即可: USE DATABASENAME; GO – Truncate the log by changing ...

  9. 文件操作putc

    putc是把一个字符写入到指定文件中,每写一个字符,文件指针自动加1. 我写了一个随机生成255字符到d:/456.txt的程序. int main() { FILE *p; int num[255] ...

  10. ubuntu14.04安装chromium以及flash插件

    之前找了好几个方法都不还用,今天突然发现,还挺简单的.命令如下: sudo apt-get updatesudo apt-get install chromium-browser#sudo add-a ...