1. 前言
  2.  
  3. 上篇文章iOS开发中的这些权限,你搞懂了吗?介绍了一些常用权限的获取和请求方法,知道这些方法的使用基本上可以搞定大部分应用的权限访问的需求。但是,这些方法并不全面,不能涵盖住所有权限访问的方法。
  4.  
  5. So,笔者在介绍一下剩下的几种权限的访问方法和一些使用上的注意事项,希望能给大家的开发过程带来一丝便利。
  6.  
  7. 最后,笔者将经常使用的权限请求方法封装开源库JLAuthorizationManager送给大家,欢迎大家pull request star~~
  8. 权限
  9.  
  10. 语音识别;
  11.  
  12. 媒体资料库/Apple Music;
  13.  
  14. Siri;
  15.  
  16. 健康数据共享;
  17.  
  18. 蓝牙;
  19.  
  20. 住宅权限(HomeKit);
  21.  
  22. 社交账号体系权限;
  23.  
  24. 活动与体能训练记录;
  25.  
  26. 广告标识;
  27. 语音识别
  28.  
  29. 引入头文件: @import Speech;
  30.  
  31. 首先判断当前应用所处的权限状态,若当前状态为NotDetermined(未确定),此时,需要调用系统提供的请求权限方法,同时也是触发系统弹窗的所在点;
  32.  
  33. 该权限涉及到的类为 SFSpeechRecognizer,具体代码如下:
  34.  
  35. - (void)p_requestSpeechRecognizerAccessWithAuthorizedHandler:(void(^)())authorizedHandler
  36. unAuthorizedHandler:(void(^)())unAuthorizedHandler{
  37.  
  38. SFSpeechRecognizerAuthorizationStatus authStatus = [SFSpeechRecognizer authorizationStatus];
  39. if (authStatus == SFSpeechRecognizerAuthorizationStatusNotDetermined) {
  40. //调用系统提供的权限访问的方法
  41. [SFSpeechRecognizer requestAuthorization:^(SFSpeechRecognizerAuthorizationStatus status) {
  42. if (status == SFSpeechRecognizerAuthorizationStatusAuthorized) {
  43. dispatch_async(dispatch_get_main_queue(), ^{
  44. //授权成功后
  45. authorizedHandler ? authorizedHandler() : nil;
  46. });
  47. }else{
  48. dispatch_async(dispatch_get_main_queue(), ^{
  49. //授权失败后
  50. unAuthorizedHandler ? unAuthorizedHandler() : nil;
  51. });
  52. }
  53. }];
  54.  
  55. }else if (authStatus == SFSpeechRecognizerAuthorizationStatusAuthorized){
  56. authorizedHandler ? authorizedHandler() : nil;
  57. }else{
  58. unAuthorizedHandler ? unAuthorizedHandler() : nil;
  59. }
  60. }
  61.  
  62. 需要注意的是,调用requestAuthorization方法的block回调是在任意的子线程中进行的,如果你需要在授权成功后刷新UI的话,需要将对应的方法置于主线程中进行,笔者将上述方法默认在主线程中进行。后续权限请求方法与此类似,不再赘述。
  63.  
  64. info.plist添加指定的配置信息,如下所示:
  65. Speech Recognizer
  66. 媒体资料库/Apple Music
  67.  
  68. 导入头文件@import MediaPlayer;
  69.  
  70. 使用类MPMediaLibrary进行权限访问,代码如下;
  71.  
  72. - (void)p_requestAppleMusicAccessWithAuthorizedHandler:(void(^)())authorizedHandler
  73. unAuthorizedHandler:(void(^)())unAuthorizedHandler{
  74. MPMediaLibraryAuthorizationStatus authStatus = [MPMediaLibrary authorizationStatus];
  75. if (authStatus == MPMediaLibraryAuthorizationStatusNotDetermined) {
  76. [MPMediaLibrary requestAuthorization:^(MPMediaLibraryAuthorizationStatus status) {
  77. if (status == MPMediaLibraryAuthorizationStatusAuthorized) {
  78. dispatch_async(dispatch_get_main_queue(), ^{
  79. authorizedHandler ? authorizedHandler() : nil;
  80. });
  81. }else{
  82. dispatch_async(dispatch_get_main_queue(), ^{
  83. unAuthorizedHandler ? unAuthorizedHandler() : nil;
  84. });
  85. }
  86. }];
  87. }else if (authStatus == MPMediaLibraryAuthorizationStatusAuthorized){
  88. authorizedHandler ? authorizedHandler() : nil;
  89. }else{
  90. unAuthorizedHandler ? unAuthorizedHandler() : nil;
  91. }
  92. }
  93.  
  94. info.plist添加指定的配置信息,如下所示:
  95. Media
  96. Siri
  97.  
  98. 导入头文件@import Intents;;
  99.  
  100. 与其他权限不同的时,使用Siri需要在XcodeCapabilities打开Siri开关,Xcode会自动生成一个xx.entitlements文件,若没有打开该开关,项目运行时会报错。
  101.  
  102. 实现代码如下:
  103.  
  104. - (void)p_requestSiriAccessWithAuthorizedHandler:(void(^)())authorizedHandler
  105. unAuthorizedHandler:(void(^)())unAuthorizedHandler{
  106. INSiriAuthorizationStatus authStatus = [INPreferences siriAuthorizationStatus];
  107. if (authStatus == INSiriAuthorizationStatusNotDetermined) {
  108. [INPreferences requestSiriAuthorization:^(INSiriAuthorizationStatus status) {
  109. if (status == INSiriAuthorizationStatusAuthorized) {
  110. dispatch_async(dispatch_get_main_queue(), ^{
  111. authorizedHandler ? authorizedHandler() : nil;
  112. });
  113. }else{
  114. dispatch_async(dispatch_get_main_queue(), ^{
  115. unAuthorizedHandler ? unAuthorizedHandler() : nil;
  116. });
  117. }
  118. }];
  119.  
  120. }else if (authStatus == INSiriAuthorizationStatusAuthorized){
  121. authorizedHandler ? authorizedHandler() : nil;
  122. }else{
  123. unAuthorizedHandler ? unAuthorizedHandler() : nil;
  124. }
  125. }
  126.  
  127. 健康数据共享
  128.  
  129. 导入头文件@import HealthKit;
  130.  
  131. 健康数据共享权限相对其他权限相对复杂一些,分为写入和读出权限.
  132.  
  133. Xcode 8中的info.plist需要设置以下两种权限:
  134.  
  135. Privacy - Health Update Usage Description
  136. Privacy - Health Share Usage Description
  137.  
  138. 具体实现代码:
  139.  
  140. //设置写入/共享的健康数据类型
  141. - (NSSet *)typesToWrite {
  142. HKQuantityType *stepType = [HKObjectType quantityTypeForIdentifier:HKQuantityTypeIdentifierStepCount];
  143. HKQuantityType *distanceType = [HKObjectType quantityTypeForIdentifier:HKQuantityTypeIdentifierDistanceWalkingRunning];
  144. return [NSSet setWithObjects:stepType,distanceType, nil];
  145. }
  146. //设置读写以下为设置的权限类型:
  147. - (NSSet *)typesToRead {
  148. HKQuantityType *stepType = [HKObjectType quantityTypeForIdentifier:HKQuantityTypeIdentifierStepCount];
  149. HKQuantityType *distanceType = [HKObjectType quantityTypeForIdentifier:HKQuantityTypeIdentifierDistanceWalkingRunning];
  150. return [NSSet setWithObjects:stepType,distanceType, nil];
  151. }
  152. //需要确定设备支持HealthKit
  153. if ([HKHealthStore isHealthDataAvailable]) {
  154. return;
  155. }
  156. HKHealthStore *healthStore = [[HKHealthStore alloc] init];
  157. NSSet * typesToShare = [self typesToWrite];
  158. NSSet * typesToRead = [self typesToRead];
  159. [healthStore requestAuthorizationToShareTypes:typesToShare readTypes:typesToRead completion:^(BOOL success, NSError * _Nullable error) {
  160. if (success) {
  161. dispatch_async(dispatch_get_main_queue(), ^{
  162. NSLog(@"Health has authorized!");
  163. });
  164. }else{
  165. dispatch_async(dispatch_get_main_queue(), ^{
  166. NSLog(@"Health has not authorized!");
  167. });
  168. }
  169. }];
  170.  
  171. 蓝牙
  172.  
  173. 需要导入头文件@import CoreBluetooth;
  174.  
  175. 蓝牙的权限检测相对其他会复杂一些,需要在代理中检测蓝牙状态;
  176.  
  177. 获取蓝牙权限:
  178.  
  179. - (void)checkBluetoothAccess {
  180. CBCentralManager *cbManager = [[CBCentralManager alloc] initWithDelegate:self queue:nil];
  181. CBManagerState state = [cbManager state];
  182. if(state == CBManagerStateUnknown) {
  183. NSLog(@"Unknown!");
  184. }
  185. else if(state == CBManagerStateUnauthorized) {
  186. NSLog(@"Unauthorized!");
  187. }
  188. else {
  189. NSLog(@"Granted!");
  190. }
  191. }
  192. - (void)centralManagerDidUpdateState:(CBCentralManager *)central {
  193. //这个代理方法会在蓝牙权限状态发生变化时被调用,并且可以根据不同的状态进行相应的修改UI或者数据访问的操作。
  194. }
  195.  
  196. 请求蓝牙权限
  197.  
  198. - (void)requestBluetoothAccess {
  199. CBCentralManager *cbManager = [[CBCentralManager alloc] initWithDelegate:self queue:nil];
  200. //该方法会显示用户同意的弹窗
  201. [cbManager scanForPeripheralsWithServices:nil options:nil];
  202. }
  203.  
  204. 住宅权限(HomeKit
  205.  
  206. 需导入头文件@import HomeKit;
  207.  
  208. HomeKit请求权限的方法如下:
  209.  
  210. - (void)requestHomeAccess {
  211. self.homeManager = [[HMHomeManager alloc] init];
  212. //当设置该代理方法后,会请求用户权限
  213. self.homeManager.delegate = self;
  214. }
  215. - (void)homeManagerDidUpdateHomes:(HMHomeManager *)manager {
  216. if (manager.homes.count > ) {
  217. // home的数量不为空,即表示用户权限已通过
  218. }
  219. else {
  220. __weak HMHomeManager *weakHomeManager = manager; // Prevent memory leak
  221. [manager addHomeWithName:@"Test Home" completionHandler:^(HMHome *home, NSError *error) {
  222.  
  223. if (!error) {
  224. //权限允许
  225. }
  226. else {
  227. if (error.code == HMErrorCodeHomeAccessNotAuthorized) {
  228. //权限不允许
  229. }
  230. else {
  231. //处理请求产生的错误
  232. }
  233. }
  234.  
  235. if (home) {
  236. [weakHomeManager removeHome:home completionHandler:^(NSError * _Nullable error) {
  237. //移除Home
  238. }];
  239. }
  240. }];
  241. }
  242. }
  243.  
  244. 社交账号体系权限
  245.  
  246. 导入头文件@import Accounts;
  247.  
  248. 获取对应的权限:
  249.  
  250. - (void)checkSocialAccountAuthorizationStatus:(NSString *)accountTypeIndentifier {
  251. ACAccountStore *accountStore = [[ACAccountStore alloc] init];
  252. ACAccountType *socialAccount = [accountStore accountTypeWithAccountTypeIdentifier:accountTypeIndentifier];
  253. if ([socialAccount accessGranted]) {
  254. NSLog(@"权限通过了");
  255. }else{
  256. NSLog(@"权限未通过!");
  257. }
  258. }
  259.  
  260. accountTypeIndentifier 可以是以下类型:
  261.  
  262. ACCOUNTS_EXTERN NSString * const ACAccountTypeIdentifierTwitter NS_AVAILABLE(NA, 5_0);
  263. ACCOUNTS_EXTERN NSString * const ACAccountTypeIdentifierFacebook NS_AVAILABLE(NA, 6_0);
  264. ACCOUNTS_EXTERN NSString * const ACAccountTypeIdentifierSinaWeibo NS_AVAILABLE(NA, 6_0);
  265. ACCOUNTS_EXTERN NSString * const ACAccountTypeIdentifierTencentWeibo NS_AVAILABLE(NA, 7_0);
  266. ACCOUNTS_EXTERN NSString * const ACAccountTypeIdentifierLinkedIn NS_AVAILABLE(NA, NA);
  267.  
  268. 请求对应的权限:
  269.  
  270. - (void)requestTwitterAccess {
  271. ACAccountStore *accountStore = [[ACAccountStore alloc] init];
  272. ACAccountType *accountType = [accountStore accountTypeWithAccountTypeIdentifier:accountTypeIdentifier];
  273.  
  274. [accountStore requestAccessToAccountsWithType: accountType options:nil completion:^(BOOL granted, NSError *error) {
  275. dispatch_async(dispatch_get_main_queue(), ^{
  276. if(granted){
  277. NSLog(@"授权通过了");
  278. }else{
  279. NSLog(@"授权未通过");
  280. }
  281. });
  282. }];
  283. }
  284.  
  285. 活动与体能训练记录
  286.  
  287. 导入头文件@import CoreMotion;
  288.  
  289. 具体实现代码:
  290.  
  291. //访问活动与体能训练记录
  292. CMMotionActivityManager *cmManager = [[CMMotionActivityManager alloc] init];
  293. NSOperationQueue *queue = [[NSOperationQueue alloc] init];
  294. [cmManager startActivityUpdatesToQueue:queue withHandler:^(CMMotionActivity *activity) {
  295.  
  296. //授权成功后,会进入Block方法内,授权失败不会进入Block方法内
  297. }];
  298.  
  299. 广告标识
  300.  
  301. 导入头文件@import AdSupport;
  302.  
  303. 获取广告标识的权限状态:
  304.  
  305. BOOL isAuthorizedForAd = [[ASIdentifierManager sharedManager] isAdvertisingTrackingEnabled];
  306.  
  307. 在使用advertisingIdentifier属性前,必须调用上述方法判断是否支持,如果上述方法返回值为NO,则advertising ID访问将会受限。
  308. 小结一下
  309.  
  310. 通过以上两篇文章的整理,有关iOS系统权限问题的处理基本上涵盖完全了;
  311.  
  312. 并不是所有的权限访问都有显式的调用方法,有些是在使用过程中进行访问的,比如定位权限、蓝牙共享权限、Homekit权限、活动与体能训练权限,这些权限在使用时注意回调方法中的权限处理;
  313.  
  314. HomeKitHealthKitSiri需要开启Capabilities中的开关,即生成projectName.entitlements文件;
  315.  
  316. 开源库JLAuthorizationManager支持集成大部分常用的权限访问,便捷使用 welcome to pull request or star

再续iOS开发中的这些权限的更多相关文章

  1. iOS开发中的这些权限,你搞懂了吗?

    APP开发避免不开系统权限的问题,如何在APP以更加友好的方式向用户展示系统权限,似乎也是开发过程中值得深思的一件事. 那如何提高APP获取iOS系统权限的通过率呢?有以下几种方式:1.在用户打开AP ...

  2. iOS开发中权限再度梳理

    前言 上篇文章iOS开发中的这些权限,你搞懂了吗?介绍了一些常用权限的获取和请求方法,知道这些方法的使用基本上可以搞定大部分应用的权限访问的需求.但是,这些方法并不全面,不能涵盖住所有权限访问的方法. ...

  3. ios开发中的小技巧

    在这里总结一些iOS开发中的小技巧,能大大方便我们的开发,持续更新. UITableView的Group样式下顶部空白处理 //分组列表头部空白处理 UIView *view = [[UIViewal ...

  4. fir.im Weekly - iOS开发中的Git流程

    本期 fir.im Weekly 收集了微博上的热转资源,包含 Android.iOS 开发工具.源码等好用的轮子,还有一些 APP 设计的 Tips,希望对你有用. 精仿知乎日报 iOS 端 @我偏 ...

  5. 在iOS开发中使用FMDB

    在iOS开发中使用FMDB 前言 SQLite (http://www.sqlite.org/docs.html) 是一个轻量级的关系数据库.iOS SDK 很早就支持了 SQLite,在使用时,只需 ...

  6. 【转】在iOS开发中使用FMDB

    本文转载自:唐巧的博客 在iOS开发中使用FMDB APR 22ND, 2012 前言 SQLite (http://www.sqlite.org/docs.html) 是一个轻量级的关系数据库.iO ...

  7. 总结iOS开发中的断点续传那些事儿

    前言 断点续传概述 断点续传就是从文件赏赐中断的地方重新开始下载或者上传数据,而不是从头文件开始.当下载大文件的时候,如果没有实现断点续传功能,那么每次出现异常或者用户主动的暂停,都会从头下载,这样很 ...

  8. iOS开发中静态库之".framework静态库"的制作及使用篇

    iOS开发中静态库之".framework静态库"的制作及使用篇 .framework静态库支持OC和swift .a静态库如何制作可参照上一篇: iOS开发中静态库之" ...

  9. iOS开发中静态库制作 之.a静态库制作及使用篇

    iOS开发中静态库之".a静态库"的制作及使用篇 一.库的简介 1.什么是库? 库是程序代码的集合,是共享程序代码的一种方式 2.库的类型? 根据源代码的公开情况,库可以分为2种类 ...

随机推荐

  1. arg max f(x) 含义

    y = f(x) 是一般常见的函数式,如果给定一个x值,f(x)函数式会赋一个值給y. y = max f(x) 代表:y 是f(x)函式所有的值中最大的output. y = arg max f(x ...

  2. swi prolog 与c#

    最近,玩了一下prolog语言,感觉还是很有意思.由于我是学c#的,所以就不禁想看看c#如何与prolog进行结合,在网上找了一下,发现有个swi prolog对c#的dll,下载官网:http:// ...

  3. Android之Action Bar

    Action Bar在实际应用中,很好地为用户提供了导航,窗口位置标识,操作点击等功能.它出现于Android3.0(API 11)之后的版本中,在2.1之后的版本中也可以使用. 添加与隐藏Actio ...

  4. Devexpress PdfViewer预览pdf,禁止下载,打印,复制

    PDFviewer控件: 参数设置: 1.屏蔽书签栏和右键菜单 2.加载文档支持路径以及流stream加载的方式 pdfViewer.MenuManager.DisposeManager(); pdf ...

  5. 1.Ventuz 介绍

    Ventoz能做什么? Ventuz是一款实时图文包装内容创作.制作和播出控制软件.Ventuz专注于高端视听内容的制作,包括交互展示和大型活动.视频墙.广播电视在线包装及演播室舞台及灯光控制等领域. ...

  6. Retrofit进行post提交json数据

    1:先看一看xutils3的提交代码 String account = editText1.getText().toString(); String password = editText2.getT ...

  7. Dictionary 小知识

    Dictionary<string, string>是一个泛型 他本身有集合的功能有时候可以把它看成数组 他的结构是这样的:Dictionary<[key], [value]> ...

  8. [转] 利用git钩子,使用python语言获取提交的文件列表

    项目有个需求,需要获取push到远程版本库的文件列表,并对文件进行特定分析.很自然的想到,要利用git钩子来触发一个脚本,实现获取文件列表的功能.比较着急使用该功能,就用python配合一些git命令 ...

  9. gulp创建完整的项目流程

    所有的环境都是在 node 安装好的基础上执行的. node -v 查看node的安装情况.npm -v查看npm 的安装情况. gulp自动化构建常用参数 1.src 读取文件或者文件夹 2.des ...

  10. Javase范式

    package Xwxx; import java.util.ArrayList; import java.util.Iterator; import java.util.function.IntBi ...