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. PHP提取字符串中的手机号正则表达式怎么写

    0. 简介 PHP通过正则表达式提取字符串中的手机号并判断运营商,简单快速方便,能提取多个手机号. 1. 代码 <?php header("content-type:text/plai ...

  2. 纸牌游戏CardBattle的设计与开发

  3. 02.全文检索和数据库like的区别

    全文检索主要应用领域:搜索引擎(百度,搜狗).站内搜索(微博搜索).电商网站(京东,淘宝) 现在不缺乏做java的人,但是缺乏有互联网背景的做Java的人.具有互联网技术的Java人才.比如说大数据, ...

  4. 【LA3713 训练指南】宇航员分组 【2-sat】

    题意 有A,B,C三个任务要分配给n个宇航员,其中每个宇航员恰好要分配一个任务.设所有n个宇航员的平均年龄为x,只有年龄大于或等于x的宇航员才能分配任务A:只有年龄严格小于x的宇航员才能分配任务B,而 ...

  5. 35. Search Insert Position (Array; Divide-and-Conquer)

    Given a sorted array and a target value, return the index if the target is found. If not, return the ...

  6. 字符串匹配——C++使用Regex

    需要#include  < regex >   匹配 regex_match ("subject", std::regex("(sub)(.*)") ...

  7. SpringBoot中使用AOP实现计算Service执行时间

    1.增加POM.XML的依赖架包 <!-- 引入 spring aop 依赖 --><dependency> <groupId>org.springframewor ...

  8. poj 3304 Segments (题意理解出错,错误的只枚举了过线段的直线)

    //枚举过每一条线段的直线, //再判断其他线段的点在直线上或被直线穿过 //即求直线与线段相交(叉积) #include<stdio.h> #include<math.h> ...

  9. HTML的DOM树结构

    在面试连续跪了两轮后,我觉得两个月的前端白学了.主要的原因是学而不思,知识是零散的,并没有组织起来.于是,我决定从今天起,复习并总结一下前端的知识点. 一般的网页浏览者看到的是网页的整体外观,前端开发 ...

  10. Android Touch 事件总结

    ---恢复内容开始--- 1.Touch事件传递机制 过程有点儿类似于栈, ViewGroup的子类有都继承它的以下3个方法: public boolean dispatchTouchEvent(Mo ...