iOS开发中权限问题:

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

  • 上述情况在开发过程中是经常遇到的,不同方式的选择会影响最后用户交互体验。这一点感悟正是源于上一周工作遇到的问题:适配iOS10,如何获取应用联网权限用以管理系统对话框的显示管理。当我把这个问题解决后,感觉有必要将常用的iOS系统权限做一个总结,以便后用。

权限分类

  • 联网权限
  • 相册权限
  • 相机、麦克风权限
  • 定位权限
  • 推送权限
  • 通讯录权限
  • 日历、备忘录权限

联网权限

  1. 引入头文件 @import CoreTelephony;
  2. 检查应用是否有联网功能
    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;
    }
  3. 应用启动后,获取应用中是否有联网权限

    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;
    };
    };

相册权限--iOS 9.0之前

  1. 导入头文件@import AssetsLibrary;
  2. 检查是否有相册权限

    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之后

  1. 导入头文件@import Photos;
  2. 检查是否有相册权限

    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;
    };
  3. 获取相册权限
     [PHPhotoLibrary requestAuthorization:^(PHAuthorizationStatus status) {
    if (status == PHAuthorizationStatusAuthorized) {
    NSLog(@"Authorized");
    }else{
    NSLog(@"Denied or Restricted");
    }
    }];

相机和麦克风权限

  1. 导入头文件@import AVFoundation;
  2. 检查是否有相机或麦克风权限

    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;
    }
  3. 获取相机或麦克风权限
    [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");
    }
    }];

定位权限

  1. 导入头文件@import CoreLocation;
  2. 由于iOS8.0之后定位方法的改变,需要在info.plist中进行配置;
  3. 检查是否有定位权限
    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;
    }
  4. 获取定位权限
    CLLocationManager *manager = [[CLLocationManager alloc] init];
    [manager requestAlwaysAuthorization];//一直获取定位信息
    [manager requestWhenInUseAuthorization];//使用的时候获取定位信息
  5. 在代理方法中查看权限是否改变
    - (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;
    } }

推送权限

  1. 检查是否有通讯权限

      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;
    }
  2. 获取推送权限

    UIUserNotificationSettings *setting = [UIUserNotificationSettings settingsForTypes:UIUserNotificationTypeSound | UIUserNotificationTypeAlert | UIUserNotificationTypeBadge categories:nil];
    [[UIApplication sharedApplication] registerUserNotificationSettings:setting];

通讯录权限

iOS9.0之前
  1. 导入头文件 @import AddressBook;
  2. 检查是否有通讯录权限

    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;
    }
  3. 获取通讯录权限
    ABAddressBookRef addressBook = ABAddressBookCreateWithOptions(NULL, NULL);
    ABAddressBookRequestAccessWithCompletion(addressBook, ^(bool granted, CFErrorRef error) {
    if (granted) {
    NSLog(@"Authorized");
    CFRelease(addressBook);
    }else{
    NSLog(@"Denied or Restricted");
    }
    });
iOS9.0及以后
  1. 导入头文件 @import Contacts;
  2. 检查是否有通讯录权限
    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; }
  3. 获取通讯录权限
    CNContactStore *contactStore = [[CNContactStore alloc] init];
    [contactStore requestAccessForEntityType:CNEntityTypeContacts completionHandler:^(BOOL granted, NSError * _Nullable error) {
    if (granted) { NSLog(@"Authorized"); }else{ NSLog(@"Denied or Restricted");
    }
    }];

日历、备忘录权限

  1. 导入头文件
  2. 检查是否有日历或者备忘录权限

  3.  typedef NS_ENUM(NSUInteger, EKEntityType) {
    EKEntityTypeEvent,//日历
    EKEntityTypeReminder //备忘
    };
  4. 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;
    }
  5. 获取日历或备忘录权限
    EKEventStore *store = [[EKEventStore alloc]init];
    [store requestAccessToEntityType:EKEntityTypeEvent completion:^(BOOL granted, NSError * _Nullable error) {
    if (granted) {
    NSLog(@"Authorized");
    }else{
    NSLog(@"Denied or Restricted");
    }
    }];

最后一点

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

    [[UIApplication sharedApplication] openURL:[NSURL URLWithString:UIApplicationOpenSettingsURLString]];

还有蓝牙...等

iOS - 系统权限(关键时刻很有用的)的更多相关文章

  1. Spring Boot 排除自动配置的 4 种方法,关键时刻很有用!

    Spring Boot 提供的自动配置非常强大,某些情况下,自动配置的功能可能不符合我们的需求,需要我们自定义配置,这个时候就需要排除/禁用 Spring Boot 某些类的自动化配置了. 比如:数据 ...

  2. IOS系统不兼容position: fixed;属性的解决方案

    position: fixed;属性在IOS系统手机上会有很明显的抖动,解决方式: 只需要在中间部分外层div添加css样式position:fixed;top:50px; bottom:50px;o ...

  3. linux非常用但很有用的命令

    查找指定目录下包含指定字符串的所有文件 grep -rl 'abc' / top查看命令的完整启动路径 top 按c top以MB为单位显示内存信息 top -M 查看内存top io趋势 pidst ...

  4. flask-login ----系统权限设计部分小结

    tips: 事实证明.开发是一项苦力活.但是代码只有自己写的才是令人感到放心的.不过仅仅是从开发角度来说.从维护和安全角度来说,当然还是引入模块比较爽 但是引入的模块总会有一些问题.碰到的最大问题就是 ...

  5. linux不常用但很有用的命令(持续完善)

    Linux登录后设置提示信息: /etc/issue 本地端登录前显示信息文件 /etc/issue.net 网络端登录前显示信息文件 /etc/motd 登陆后显示信息文件 可以添加以下几个常用选项 ...

  6. [转]通过apk签名使应用程序有系统权限

    [转]通过apk签名使应用程序有系统权限 (2013-01-08 13:40:50) 转载▼ 标签: it 分类: Android 出处:http://blog.csdn.net/doom66151/ ...

  7. iOS 苹果官方 Crash文件分析方法 (iOS系统Crash文件分析方法)

    时间2013-08-20 12:49:20 GoWhich原文  http://www.gowhich.com/blog/view/id/343 苹果官方 Crash文件分析方法 (iOS系统Cras ...

  8. 26、生鲜电商平台-RBAC系统权限的设计与架构

    说明:根据上面的需求描述以及对需求的分析,我们得知通常的一个中小型系统对于权限系统所需实现的功能以及非功能性的需求,在下面我们将根据需求从技术角度上分析实现的策略以及基于目前两种比较流行的权限设计思想 ...

  9. Java生鲜电商平台-RBAC系统权限的设计与架构

    Java生鲜电商平台-RBAC系统权限的设计与架构 说明:根据上面的需求描述以及对需求的分析,我们得知通常的一个中小型系统对于权限系统所需实现的功能以及非功能性的需求,在下面我们将根据需求从技术角度上 ...

随机推荐

  1. 关于阅读JDK源码的准备

    说明:本篇是给自己看的. 笑 最近突然有冲动 想研究下JDK的源码,搜索了一番,基本上推荐从集合开始,精华部分包括:集合.IO.多线程.网络编程. 虚拟机部分先放一放吧,感觉现在不适合我这种半路出家的 ...

  2. Spring JDBC调用存储函数

    以下示例将演示spring jdbc如何调用存储函数.在这个示例中将通过调用存储函数来读取Student表中的一个可用记录信息.传递一个ID并获取学生的姓名. 语法: SimpleJdbcCall j ...

  3. LintCode #1 A + B 问题

    分析:以3 + 5为例 3的二进制为 1 1,5的二进制为 1 0 1,可以这样做:1先给这两个数加起来不考虑进位,这样得到的结果为 1 1 0,会发现与^得到的结果相同,与是先给两个数 做^运算:2 ...

  4. (实用)Ubuntu 开启NFS服务

    本文介绍如何在Ubuntu下开启NFS文件系统,从而挂载网络上其他机器的文件系统. NFS, Network File System, 即网络文件系统,通常NFS有提供者和使用者,提供者export自 ...

  5. Linux 下 Nginx + JDK + Tomcat + MySQL 安装指南

    转载请注明出处:http://blog.csdn.net/smartbetter/article/details/52026342 Nginx 是一款高性能的 http 服务器/反向代理服务器/电子邮 ...

  6. java注解自定义使用

    Java提供了4种注解,专门负责新注解的创建: @Target: 表示该注解可以用于什么地方,可能的ElementType参数有:CONSTRUCTOR:构造器的声明FIELD:域声明(包括enum实 ...

  7. git fetch , git pull

    要讲清楚git fetch,git pull,必须要附加讲清楚git remote,git merge .远程repo, branch . commit-id 以及 FETCH_HEAD. 1. [g ...

  8. 多目标线性规划求解方法及matlab实现

    转载: https://blog.csdn.net/wzl1997/article/details/79120323

  9. 简单理解AOP(面向切面编程)

    AOP为Aspect Oriented Programming的缩写,意为:面向切面编程,通过预编译方式和运行期动态代理实现程序功能的统一维护的一种技术. AOP与OOP是面向不同领域的两种设计思想. ...

  10. nodejs的__dirname与__filename

    __filename变量获取当前模块文件的带有完整绝对路径的文件名:[包含文件名本身的绝对路径] __dirname变量获得当前文件所在目录的完整目录名.[不包含文件名本身的绝对路径] 该方法用于获取 ...