在人們越來越注意隱私的今天箫柳,用戶的app的權(quán)限的下放也越來越謹(jǐn)慎。
得到權(quán)限的過程啥供,一般分為兩種:1. 一次獲取要用的所有權(quán)限悯恍; 2.用什么功能獲取什么權(quán)限。當(dāng)然兩種方式各有有缺點(diǎn)伙狐,方法一涮毫,用戶體驗(yàn)好,但是用戶可能不完全明白權(quán)限的用途贷屎。方法二罢防,也是現(xiàn)在大部分app的做法,使用過程中不斷的彈框獲取提示獲取權(quán)限豫尽,不過這樣用戶也明白權(quán)限的用途篙梢。
下面列舉一下主要的權(quán)限獲取和檢驗(yàn)方法(iOS8
以后的版本為例):
-
相冊
//頭文件 iOS8以后版本可用PhotoKit
#import <Photos/Photos.h>
檢查是否有相冊權(quán)限
PHAuthorizationStatus photoAuthStatus = [PHPhotoLibrary authorizationStatus];
switch (photoAuthStatus) {
case PHAuthorizationStatusNotDetermined:
NSLog(@"未詢問用戶是否授權(quán)");
break;
case PHAuthorizationStatusRestricted:
NSLog(@"未授權(quán),例如家長控制");
break;
case PHAuthorizationStatusDenied:
NSLog(@"未授權(quán)美旧,用戶拒絕造成的");
break;
case PHAuthorizationStatusAuthorized:
NSLog(@"同意授權(quán)相冊");
break;
default:
break;
}
獲取相冊權(quán)限
[PHPhotoLibrary requestAuthorization:^(PHAuthorizationStatus status) {
if (status == PHAuthorizationStatusAuthorized) {
NSLog(@"用戶同意授權(quán)相冊");
}else {
NSLog(@"用戶拒絕授權(quán)相冊");
}
}];
-
相機(jī)和麥克風(fēng)
//頭文件
#import <AVFoundation/AVFoundation.h>
檢查是否有相機(jī)權(quán)限或者麥克風(fēng)權(quán)限
AVF_EXPORT NSString *const AVMediaTypeVideo NS_AVAILABLE(10_7, 4_0); //相機(jī)
AVF_EXPORT NSString *const AVMediaTypeAudio NS_AVAILABLE(10_7, 4_0);//麥克風(fēng)
AVAuthorizationStatus videoAuthStatus = [AVCaptureDevice authorizationStatusForMediaType:AVMediaTypeVideo];
switch (videoAuthStatus) {
case AVAuthorizationStatusNotDetermined:
NSLog(@"未詢問用戶是否授權(quán)");
break;
case AVAuthorizationStatusRestricted:
NSLog(@"未授權(quán)渤滞,例如家長控制");
break;
case AVAuthorizationStatusDenied:
NSLog(@"未授權(quán),用戶拒絕造成的");
break;
case AVAuthorizationStatusAuthorized:
NSLog(@"同意授權(quán)相機(jī)");
break;
default:
break;
}
獲取相機(jī)權(quán)限或者麥克風(fēng)權(quán)限
[AVCaptureDevice requestAccessForMediaType:AVMediaTypeVideo completionHandler:^(BOOL granted) {
if (granted){
NSLog(@"用戶同意授權(quán)相機(jī)");
}else {
NSLog(@"用戶拒絕授權(quán)相機(jī)");
}
}];
-
推送
檢查是否有推送權(quán)限
UIUserNotificationSettings *notificationSettings = [[UIApplication sharedApplication] currentUserNotificationSettings];
switch (notificationSettings.types) {
case UIUserNotificationTypeNone:
NSLog(@"沒有推送權(quán)限");
break;
case UIUserNotificationTypeBadge:
NSLog(@"帶角標(biāo)的推送");
break;
case UIUserNotificationTypeSound:
NSLog(@"帶聲音的推送");
break;
case UIUserNotificationTypeAlert:
NSLog(@"帶通知的推送");
break;
default:
break;
}
獲取推送權(quán)限
UIUserNotificationSettings *notificationSettings = [UIUserNotificationSettings settingsForTypes:UIUserNotificationTypeAlert|UIUserNotificationTypeBadge|UIUserNotificationTypeSound categories:nil];
[[UIApplication sharedApplication] registerUserNotificationSettings:notificationSettings];
-
通訊錄
//頭文件 iOS9之后蘋果推薦使用<Contacts/Contacts.h>
#import <AddressBook/AddressBook.h>
檢查是否有通訊錄權(quán)限
ABAuthorizationStatus authorizationStatus = ABAddressBookGetAuthorizationStatus();
switch (authorizationStatus) {
case kABAuthorizationStatusNotDetermined:
NSLog(@"未詢問用戶是否授權(quán)");
break;
case kABAuthorizationStatusRestricted:
NSLog(@"未授權(quán)榴嗅,例如家長控制");
break;
case kABAuthorizationStatusDenied:
NSLog(@"未授權(quán)妄呕,用戶拒絕造成的");
break;
case kABAuthorizationStatusAuthorized:
NSLog(@"同意授權(quán)通訊錄");
break;
default:
break;
}
獲取通訊錄權(quán)限
ABAddressBookRef addressBook = ABAddressBookCreateWithOptions(NULL, NULL);
ABAddressBookRequestAccessWithCompletion(addressBook, ^(bool granted, CFErrorRef error) {
if (granted) {
NSLog(@"用戶同意授權(quán)通訊錄");
CFRelease(addressBook);
} else {
NSLog(@"用戶拒絕授權(quán)通訊錄");
}
});
- 日歷和備忘錄
//頭文件
#import <EventKit/EventKit.h>
檢查是否有日歷權(quán)限或者備忘錄權(quán)限
typedef NS_ENUM(NSUInteger, EKEntityType) {
EKEntityTypeEvent,//日歷
EKEntityTypeReminder//備忘錄
};
EKAuthorizationStatus status = [EKEventStore authorizationStatusForEntityType:EKEntityTypeEvent];
switch (status) {
case EKAuthorizationStatusNotDetermined:
NSLog(@"未詢問用戶是否授權(quán)");
break;
case EKAuthorizationStatusRestricted:
NSLog(@"未授權(quán),例如家長控制");
break;
case EKAuthorizationStatusDenied:
NSLog(@"未授權(quán)嗽测,用戶拒絕造成的");
break;
case EKAuthorizationStatusAuthorized:
NSLog(@"同意授權(quán)日歷");
break;
default:
break;
}
獲取日歷權(quán)限或者備忘錄權(quán)限
EKEventStore *eventStore = [[EKEventStore alloc] init];
[eventStore requestAccessToEntityType:EKEntityTypeEvent
completion:^(BOOL granted, NSError *error) {
if (error) {
NSLog(@"日歷出現(xiàn)了錯(cuò)誤");
return;
}
if (granted) {
NSLog(@"用戶同意授權(quán)日歷");
} else {
NSLog(@"用戶拒絕授權(quán)日歷");
}
}];
-
定位
//頭文件
#import <CoreLocation/CoreLocation.h>
由于iOS8之后定位方法的改變绪励,需要現(xiàn)在info.plist中進(jìn)行配置
檢查是否有定位權(quán)限
BOOL isLocation = [CLLocationManager locationServicesEnabled]; //是否開啟定位服務(wù)
if (!isLocation) {
NSLog(@"用戶未開啟定位");
return ;
}
CLAuthorizationStatus locationStatus = [CLLocationManager authorizationStatus];
switch (locationStatus) {
case kCLAuthorizationStatusNotDetermined:
NSLog(@"未詢問用戶是否授權(quán)");
break;
case kCLAuthorizationStatusRestricted:
NSLog(@"未授權(quán),例如家長控制");
break;
case kCLAuthorizationStatusDenied:
NSLog(@"未授權(quán)唠粥,用戶拒絕造成的");
break;
case kCLAuthorizationStatusAuthorizedAlways:
NSLog(@"同意授權(quán)一直獲取定位信息");
break;
case kCLAuthorizationStatusAuthorizedWhenInUse:
NSLog(@"同意授權(quán)在使用時(shí)獲取定位信息");
break;
default:
break;
}
獲取定位權(quán)限
CLLocationManager *manager = [[CLLocationManager alloc] init];
[manager requestAlwaysAuthorization];//一直獲取定位信息
[manager requestWhenInUseAuthorization];//使用時(shí)獲取定位信息
定位中還有一個(gè)代理方法疏魏,可以查看權(quán)限改變
- (void)locationManager:(CLLocationManager *)manager didChangeAuthorizationStatus:(CLAuthorizationStatus)status{
switch (status) {
case kCLAuthorizationStatusNotDetermined:
NSLog(@"未詢問用戶是否授權(quán)");
break;
case kCLAuthorizationStatusRestricted:
NSLog(@"未授權(quán),例如家長控制");
break;
case kCLAuthorizationStatusDenied:
NSLog(@"未授權(quán)晤愧,用戶拒絕造成的");
break;
case kCLAuthorizationStatusAuthorizedAlways:
NSLog(@"同意授權(quán)一直獲取定位信息");
break;
case kCLAuthorizationStatusAuthorizedWhenInUse:
NSLog(@"同意授權(quán)在使用時(shí)獲取定位信息");
break;
default:
break;
}
}
所有獲取權(quán)限的方法用戶進(jìn)行了第一次操作之后大莫,都會(huì)沒有用了,iOS8之后蘋果把這些設(shè)置都整合在了一起官份,通過下面這個(gè)方法則可以打開只厘。
[[UIApplication sharedApplication] openURL:[NSURL URLWithString:UIApplicationOpenSettingsURLString]];
最后這是一個(gè)非常優(yōu)秀的權(quán)限管理庫PermissionScope
本文的Demo