再续iOS开发中的这些权限
前言 上篇文章iOS开发中的这些权限,你搞懂了吗?介绍了一些常用权限的获取和请求方法,知道这些方法的使用基本上可以搞定大部分应用的权限访问的需求。但是,这些方法并不全面,不能涵盖住所有权限访问的方法。 So,笔者在介绍一下剩下的几种权限的访问方法和一些使用上的注意事项,希望能给大家的开发过程带来一丝便利。 最后,笔者将经常使用的权限请求方法封装开源库JLAuthorizationManager送给大家,欢迎大家pull request 和 star~~
权限 语音识别; 媒体资料库/Apple Music; Siri; 健康数据共享; 蓝牙; 住宅权限(HomeKit); 社交账号体系权限; 活动与体能训练记录; 广告标识;
语音识别 引入头文件: @import Speech; 首先判断当前应用所处的权限状态,若当前状态为NotDetermined(未确定),此时,需要调用系统提供的请求权限方法,同时也是触发系统弹窗的所在点; 该权限涉及到的类为 SFSpeechRecognizer,具体代码如下: - (void)p_requestSpeechRecognizerAccessWithAuthorizedHandler:(void(^)())authorizedHandler
unAuthorizedHandler:(void(^)())unAuthorizedHandler{ SFSpeechRecognizerAuthorizationStatus authStatus = [SFSpeechRecognizer authorizationStatus];
if (authStatus == SFSpeechRecognizerAuthorizationStatusNotDetermined) {
//调用系统提供的权限访问的方法
[SFSpeechRecognizer requestAuthorization:^(SFSpeechRecognizerAuthorizationStatus status) {
if (status == SFSpeechRecognizerAuthorizationStatusAuthorized) {
dispatch_async(dispatch_get_main_queue(), ^{
//授权成功后
authorizedHandler ? authorizedHandler() : nil;
});
}else{
dispatch_async(dispatch_get_main_queue(), ^{
//授权失败后
unAuthorizedHandler ? unAuthorizedHandler() : nil;
});
}
}]; }else if (authStatus == SFSpeechRecognizerAuthorizationStatusAuthorized){
authorizedHandler ? authorizedHandler() : nil;
}else{
unAuthorizedHandler ? unAuthorizedHandler() : nil;
}
} 需要注意的是,调用requestAuthorization方法的block回调是在任意的子线程中进行的,如果你需要在授权成功后刷新UI的话,需要将对应的方法置于主线程中进行,笔者将上述方法默认在主线程中进行。后续权限请求方法与此类似,不再赘述。 在info.plist添加指定的配置信息,如下所示:
Speech Recognizer
媒体资料库/Apple Music 导入头文件@import MediaPlayer; 使用类MPMediaLibrary进行权限访问,代码如下; - (void)p_requestAppleMusicAccessWithAuthorizedHandler:(void(^)())authorizedHandler
unAuthorizedHandler:(void(^)())unAuthorizedHandler{
MPMediaLibraryAuthorizationStatus authStatus = [MPMediaLibrary authorizationStatus];
if (authStatus == MPMediaLibraryAuthorizationStatusNotDetermined) {
[MPMediaLibrary requestAuthorization:^(MPMediaLibraryAuthorizationStatus status) {
if (status == MPMediaLibraryAuthorizationStatusAuthorized) {
dispatch_async(dispatch_get_main_queue(), ^{
authorizedHandler ? authorizedHandler() : nil;
});
}else{
dispatch_async(dispatch_get_main_queue(), ^{
unAuthorizedHandler ? unAuthorizedHandler() : nil;
});
}
}];
}else if (authStatus == MPMediaLibraryAuthorizationStatusAuthorized){
authorizedHandler ? authorizedHandler() : nil;
}else{
unAuthorizedHandler ? unAuthorizedHandler() : nil;
}
} 在info.plist添加指定的配置信息,如下所示:
Media
Siri 导入头文件@import Intents;; 与其他权限不同的时,使用Siri需要在Xcode中Capabilities打开Siri开关,Xcode会自动生成一个xx.entitlements文件,若没有打开该开关,项目运行时会报错。 实现代码如下: - (void)p_requestSiriAccessWithAuthorizedHandler:(void(^)())authorizedHandler
unAuthorizedHandler:(void(^)())unAuthorizedHandler{
INSiriAuthorizationStatus authStatus = [INPreferences siriAuthorizationStatus];
if (authStatus == INSiriAuthorizationStatusNotDetermined) {
[INPreferences requestSiriAuthorization:^(INSiriAuthorizationStatus status) {
if (status == INSiriAuthorizationStatusAuthorized) {
dispatch_async(dispatch_get_main_queue(), ^{
authorizedHandler ? authorizedHandler() : nil;
});
}else{
dispatch_async(dispatch_get_main_queue(), ^{
unAuthorizedHandler ? unAuthorizedHandler() : nil;
});
}
}]; }else if (authStatus == INSiriAuthorizationStatusAuthorized){
authorizedHandler ? authorizedHandler() : nil;
}else{
unAuthorizedHandler ? unAuthorizedHandler() : nil;
}
} 健康数据共享 导入头文件@import HealthKit; 健康数据共享权限相对其他权限相对复杂一些,分为写入和读出权限. 在Xcode 8中的info.plist需要设置以下两种权限: 、Privacy - Health Update Usage Description
、Privacy - Health Share Usage Description 具体实现代码: //设置写入/共享的健康数据类型
- (NSSet *)typesToWrite {
HKQuantityType *stepType = [HKObjectType quantityTypeForIdentifier:HKQuantityTypeIdentifierStepCount];
HKQuantityType *distanceType = [HKObjectType quantityTypeForIdentifier:HKQuantityTypeIdentifierDistanceWalkingRunning];
return [NSSet setWithObjects:stepType,distanceType, nil];
}
//设置读写以下为设置的权限类型:
- (NSSet *)typesToRead {
HKQuantityType *stepType = [HKObjectType quantityTypeForIdentifier:HKQuantityTypeIdentifierStepCount];
HKQuantityType *distanceType = [HKObjectType quantityTypeForIdentifier:HKQuantityTypeIdentifierDistanceWalkingRunning];
return [NSSet setWithObjects:stepType,distanceType, nil];
}
//需要确定设备支持HealthKit
if ([HKHealthStore isHealthDataAvailable]) {
return;
}
HKHealthStore *healthStore = [[HKHealthStore alloc] init];
NSSet * typesToShare = [self typesToWrite];
NSSet * typesToRead = [self typesToRead];
[healthStore requestAuthorizationToShareTypes:typesToShare readTypes:typesToRead completion:^(BOOL success, NSError * _Nullable error) {
if (success) {
dispatch_async(dispatch_get_main_queue(), ^{
NSLog(@"Health has authorized!");
});
}else{
dispatch_async(dispatch_get_main_queue(), ^{
NSLog(@"Health has not authorized!");
});
}
}]; 蓝牙 需要导入头文件@import CoreBluetooth; 蓝牙的权限检测相对其他会复杂一些,需要在代理中检测蓝牙状态; 获取蓝牙权限: - (void)checkBluetoothAccess {
CBCentralManager *cbManager = [[CBCentralManager alloc] initWithDelegate:self queue:nil];
CBManagerState state = [cbManager state];
if(state == CBManagerStateUnknown) {
NSLog(@"Unknown!");
}
else if(state == CBManagerStateUnauthorized) {
NSLog(@"Unauthorized!");
}
else {
NSLog(@"Granted!");
}
}
- (void)centralManagerDidUpdateState:(CBCentralManager *)central {
//这个代理方法会在蓝牙权限状态发生变化时被调用,并且可以根据不同的状态进行相应的修改UI或者数据访问的操作。
} 请求蓝牙权限 - (void)requestBluetoothAccess {
CBCentralManager *cbManager = [[CBCentralManager alloc] initWithDelegate:self queue:nil];
//该方法会显示用户同意的弹窗
[cbManager scanForPeripheralsWithServices:nil options:nil];
} 住宅权限(HomeKit) 需导入头文件@import HomeKit; HomeKit请求权限的方法如下: - (void)requestHomeAccess {
self.homeManager = [[HMHomeManager alloc] init];
//当设置该代理方法后,会请求用户权限
self.homeManager.delegate = self;
}
- (void)homeManagerDidUpdateHomes:(HMHomeManager *)manager {
if (manager.homes.count > ) {
// home的数量不为空,即表示用户权限已通过
}
else {
__weak HMHomeManager *weakHomeManager = manager; // Prevent memory leak
[manager addHomeWithName:@"Test Home" completionHandler:^(HMHome *home, NSError *error) { if (!error) {
//权限允许
}
else {
if (error.code == HMErrorCodeHomeAccessNotAuthorized) {
//权限不允许
}
else {
//处理请求产生的错误
}
} if (home) {
[weakHomeManager removeHome:home completionHandler:^(NSError * _Nullable error) {
//移除Home
}];
}
}];
}
} 社交账号体系权限 导入头文件@import Accounts; 获取对应的权限: - (void)checkSocialAccountAuthorizationStatus:(NSString *)accountTypeIndentifier {
ACAccountStore *accountStore = [[ACAccountStore alloc] init];
ACAccountType *socialAccount = [accountStore accountTypeWithAccountTypeIdentifier:accountTypeIndentifier];
if ([socialAccount accessGranted]) {
NSLog(@"权限通过了");
}else{
NSLog(@"权限未通过!");
}
} accountTypeIndentifier 可以是以下类型: ACCOUNTS_EXTERN NSString * const ACAccountTypeIdentifierTwitter NS_AVAILABLE(NA, 5_0);
ACCOUNTS_EXTERN NSString * const ACAccountTypeIdentifierFacebook NS_AVAILABLE(NA, 6_0);
ACCOUNTS_EXTERN NSString * const ACAccountTypeIdentifierSinaWeibo NS_AVAILABLE(NA, 6_0);
ACCOUNTS_EXTERN NSString * const ACAccountTypeIdentifierTencentWeibo NS_AVAILABLE(NA, 7_0);
ACCOUNTS_EXTERN NSString * const ACAccountTypeIdentifierLinkedIn NS_AVAILABLE(NA, NA); 请求对应的权限: - (void)requestTwitterAccess {
ACAccountStore *accountStore = [[ACAccountStore alloc] init];
ACAccountType *accountType = [accountStore accountTypeWithAccountTypeIdentifier:accountTypeIdentifier]; [accountStore requestAccessToAccountsWithType: accountType options:nil completion:^(BOOL granted, NSError *error) {
dispatch_async(dispatch_get_main_queue(), ^{
if(granted){
NSLog(@"授权通过了");
}else{
NSLog(@"授权未通过");
}
});
}];
} 活动与体能训练记录 导入头文件@import CoreMotion; 具体实现代码: //访问活动与体能训练记录
CMMotionActivityManager *cmManager = [[CMMotionActivityManager alloc] init];
NSOperationQueue *queue = [[NSOperationQueue alloc] init];
[cmManager startActivityUpdatesToQueue:queue withHandler:^(CMMotionActivity *activity) { //授权成功后,会进入Block方法内,授权失败不会进入Block方法内
}]; 广告标识 导入头文件@import AdSupport; 获取广告标识的权限状态: BOOL isAuthorizedForAd = [[ASIdentifierManager sharedManager] isAdvertisingTrackingEnabled]; 在使用advertisingIdentifier属性前,必须调用上述方法判断是否支持,如果上述方法返回值为NO,则advertising ID访问将会受限。
小结一下 通过以上两篇文章的整理,有关iOS系统权限问题的处理基本上涵盖完全了; 并不是所有的权限访问都有显式的调用方法,有些是在使用过程中进行访问的,比如定位权限、蓝牙共享权限、Homekit权限、活动与体能训练权限,这些权限在使用时注意回调方法中的权限处理; HomeKit、HealthKit、Siri需要开启Capabilities中的开关,即生成projectName.entitlements文件; 开源库JLAuthorizationManager支持集成大部分常用的权限访问,便捷使用 welcome to pull request or star;
再续iOS开发中的这些权限的更多相关文章
- iOS开发中的这些权限,你搞懂了吗?
APP开发避免不开系统权限的问题,如何在APP以更加友好的方式向用户展示系统权限,似乎也是开发过程中值得深思的一件事. 那如何提高APP获取iOS系统权限的通过率呢?有以下几种方式:1.在用户打开AP ...
- iOS开发中权限再度梳理
前言 上篇文章iOS开发中的这些权限,你搞懂了吗?介绍了一些常用权限的获取和请求方法,知道这些方法的使用基本上可以搞定大部分应用的权限访问的需求.但是,这些方法并不全面,不能涵盖住所有权限访问的方法. ...
- ios开发中的小技巧
在这里总结一些iOS开发中的小技巧,能大大方便我们的开发,持续更新. UITableView的Group样式下顶部空白处理 //分组列表头部空白处理 UIView *view = [[UIViewal ...
- fir.im Weekly - iOS开发中的Git流程
本期 fir.im Weekly 收集了微博上的热转资源,包含 Android.iOS 开发工具.源码等好用的轮子,还有一些 APP 设计的 Tips,希望对你有用. 精仿知乎日报 iOS 端 @我偏 ...
- 在iOS开发中使用FMDB
在iOS开发中使用FMDB 前言 SQLite (http://www.sqlite.org/docs.html) 是一个轻量级的关系数据库.iOS SDK 很早就支持了 SQLite,在使用时,只需 ...
- 【转】在iOS开发中使用FMDB
本文转载自:唐巧的博客 在iOS开发中使用FMDB APR 22ND, 2012 前言 SQLite (http://www.sqlite.org/docs.html) 是一个轻量级的关系数据库.iO ...
- 总结iOS开发中的断点续传那些事儿
前言 断点续传概述 断点续传就是从文件赏赐中断的地方重新开始下载或者上传数据,而不是从头文件开始.当下载大文件的时候,如果没有实现断点续传功能,那么每次出现异常或者用户主动的暂停,都会从头下载,这样很 ...
- iOS开发中静态库之".framework静态库"的制作及使用篇
iOS开发中静态库之".framework静态库"的制作及使用篇 .framework静态库支持OC和swift .a静态库如何制作可参照上一篇: iOS开发中静态库之" ...
- iOS开发中静态库制作 之.a静态库制作及使用篇
iOS开发中静态库之".a静态库"的制作及使用篇 一.库的简介 1.什么是库? 库是程序代码的集合,是共享程序代码的一种方式 2.库的类型? 根据源代码的公开情况,库可以分为2种类 ...
随机推荐
- POJ 3275 Floyd传递闭包
题意:Farmer John想按照奶牛产奶的能力给她们排序.现在已知有N头奶牛(1 ≤ N ≤ 1,000).FJ通过比较,已经知道了M(1 ≤ M ≤ 10,000)对相对关系.每一对关系表示为&q ...
- POJ 3258 (NOIP2015 D2T1跳石头)
河中跳房子 总时间限制: 1000ms 内存限制: 65536kB 描述 每年奶牛们都要举办各种特殊版本的跳房子比赛,包括在河里从一个岩石跳到另一个岩石.这项激动人心的活动在一条长长的笔直河道中进行, ...
- html行级元素和块级元素以及css转换
之前有说过html的标签是有语义的,当然也就有一些默认的样式,比如标题有h1···h6,他们的字体由大至小一次递减,字体比一般字体要加粗. 这样也就有了行级元素和块级元素,下面来看看什么是行级元素什么 ...
- PHP入门及服务环境配置(Nginx+PHP)
PHP入门及服务环境配置(Nginx+PHP) PHP入门 PHP维基百科: PHP(全称:PHP:Hypertext Preprocessor,即"PHP:超文本预处理器")是一 ...
- 洛谷 P1328 生活大爆炸版石头剪刀布 模拟
很简单 Code: #include<cstdio> #include<queue> using namespace std; queue<int>A; queue ...
- 实验一:JAVA实验环境搭建 ,JDK下载与安装及 Eclipse下载与安装
一.搭建JAVA实验环境 1.JDK的下载 (1)打开 IE 浏览器,输入网址“http://www.oracle.com/index.html”,浏览 Oracle 官方主页.鼠标双击Downloa ...
- springboot 打包下载数据
//文件打包下载 public static HttpServletResponse downLoadFiles(List<File> files, Htt ...
- P1085 不高兴的津津
... 题目描述 津津上初中了.妈妈认为津津应该更加用功学习,所以津津除了上学之外,还要参加妈妈为她报名的各科复习班.另外每周妈妈还会送她去学习朗诵.舞蹈和钢琴.但是津津如果一天上课超过八个小时就会不 ...
- python中的and、or 操作符
在python中 非空 非零的数都为真 1. 其"and"操作符返回的结果是决定表达式结果的值:两边条件都为真则结果为真,有一假则为假 1) 当and两边条件为“真”时,返回的是a ...
- J2EE提高之知识清单
Oracle数据库 JDBC事务 Spring事务 SOA XML/JSON redis/memcached 反射,类加载,JVM 工具类:UML, Maven, 性能类:CPU监控,memary监控 ...