- (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的话,需要将对应的方法置于主线程中进行,笔者将上述方法默认在主线程中进行。后续权限请求方法与此类似,不再赘述。Speech Recognizer
- (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;
}
}
Media
- (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;
}
}
info.plist
需要设置以下两种权限:1、Privacy - Health Update Usage Description
2、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!");
});
}
}];
- (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
请求权限的方法如下:- (void)requestHomeAccess {
self.homeManager = [[HMHomeManager alloc] init];
//当设置该代理方法后,会请求用户权限
self.homeManager.delegate = self;
}
- (void)homeManagerDidUpdateHomes:(HMHomeManager *)manager {
if (manager.homes.count > 0) {
// 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
}];
}
}];
}
}
- (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(@"授权未通过");
}
});
}];
}
//访问活动与体能训练记录
CMMotionActivityManager *cmManager = [[CMMotionActivityManager alloc] init];
NSOperationQueue *queue = [[NSOperationQueue alloc] init];
[cmManager startActivityUpdatesToQueue:queue withHandler:^(CMMotionActivity *activity) {
//授权成功后,会进入Block方法内,授权失败不会进入Block方法内
}];
BOOL isAuthorizedForAd = [[ASIdentifierManager sharedManager] isAdvertisingTrackingEnabled];
advertisingIdentifier
属性前,必须调用上述方法判断是否支持,如果上述方法返回值为NO
,则advertising ID
访问将会受限。定位权限
、蓝牙共享权限
、Homekit权限
、活动与体能训练权限
,这些权限在使用时注意回调方法中的权限处理;HomeKit
、HealthKit
、Siri
需要开启Capabilities
中的开关,即生成projectName.entitlements
文件;