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. 找不到 org/springframework/dao/support/PersistenceExceptionTranslator

    如果用的spring2  则原因是缺少spring-dao.jar 如果用的是spring3(我就栽这儿了) 则原因是缺少org.springframework.transaction-3.0.4.R ...

  2. 反射与dynamic

    反射 var a = Assembly.GetExecutingAssembly(); Type type = a.GetType("CLRTest.ReflectClass"); ...

  3. git的突出解决--git rebase之abort、continue、skip

    (1)应用实例描述 假设在github或者gitoschina上建立了一个项目,默认分支为master分支,远程master分支上c.sh文件内容: 开发者A.B分别将项目拷贝到自己本地进行开发 某一 ...

  4. 解剖Nginx·自动脚本篇(4)工具型脚本系列

    目录 auto/have 向自动配置头文件追加可用宏定义(objs/ngx_auto_config.h) auto/nohave 向自动配置头文件追加不可用宏定义(objs/ngx_auto_conf ...

  5. windows运行打开服务命令的方法 :

    windows运行打开服务命令的方法 : 在开始->运行,输入以下命令 1. gpedit.msc-----组策略 2. sndrec32-------录音机 3. Nslookup------ ...

  6. 使用lucene query的CharFilter 去掉字符中的script脚本和html标签

    1.准备数据,这里我从数据库读取一个带有html标签和script脚本的数据

  7. Python 中 "is" 与 "==" 操作有什么区别?

    转自:https://foofish.net/what-is-difference-between-is-and-euqals.html 在 Python 中,比较两个对象(变量)是否相等,可以用 & ...

  8. 洛谷 P3478 [POI2008]STA-Station

    题目描述 The first stage of train system reform (that has been described in the problem Railways of the ...

  9. redis集群部署及常用的操作命令(上)

    简单说下自己测试搭建简单的redis集群的大体步骤: 1.首先你的有6个redis(官方说最少6个,3master,3slave),可以先在一台机器上搭建,搭建到多台上应该只需要改变启动命令即可(可能 ...

  10. 工作流系统webservice服务

    http://blog.csdn.net/zhengzhb/article/details/7477616