自從iOS8增加了權(quán)限需要征得用戶同意后报辱,后續(xù)iOS對權(quán)限的要求越來嚴(yán)格,記錄一下各種權(quán)限的獲取方法
1瘦癌、定位權(quán)限(info.plist需要添加LocationWhenInUseUsageDescription + LocationAlwaysUsageDescription)
需要獲取用戶此時此刻的位置信息的時候需要使用到定位權(quán)限看锉。
使用到了#import <CoreLocation/CoreLocation.h> // 定位框架
權(quán)限狀態(tài)獲取方法是:
CLAuthorizationStatus locationstats = [CLLocationManager authorizationStatus];
獲取到的狀態(tài)有:
typedef NS_ENUM(int, CLAuthorizationStatus) {
kCLAuthorizationStatusNotDetermined = 0, // 還未請求過權(quán)限,一般是APP首次安裝否副,然后第一次請求權(quán)限的時候才會出現(xiàn)這個狀態(tài),然后需要主動觸發(fā)權(quán)限請求
kCLAuthorizationStatusRestricted, // 拒絕狀態(tài)
kCLAuthorizationStatusDenied,// 用戶已允許狀態(tài)
kCLAuthorizationStatusAuthorizedAlways NS_ENUM_AVAILABLE(10_12, 8_0),// “始終”定位
kCLAuthorizationStatusAuthorizedWhenInUse NS_ENUM_AVAILABLE(NA, 8_0),// “使用應(yīng)用期間”定位
kCLAuthorizationStatusAuthorized NS_ENUM_DEPRECATED(10_6, NA, 2_0, 8_0, "Use kCLAuthorizationStatusAuthorizedAlways") // 此枚舉已經(jīng)廢棄崎坊,使用kCLAuthorizationStatusAuthorizedAlways替代
};
當(dāng)系統(tǒng)API返回的狀態(tài)是kCLAuthorizationStatusNotDetermined還未授權(quán)過的狀態(tài)的時候备禀,我們需要主動發(fā)起授權(quán)請求,如果定位僅僅是“在APP使用期間”才涉及到定位需求的話奈揍,那么使用requestWhenInUseAuthorization方法請求權(quán)限曲尸,如果是無論什么時候都需要定位權(quán)限的話,那么使用requestAlwaysAuthorization方法請求權(quán)限男翰,請求方法如下:
CLLocationManager * locationManager = [[CLLocationManager alloc] init];
locationManager.delegate = self;
// 在app打開期間使用定位權(quán)限
[locationManager requestWhenInUseAuthorization];
// app在后臺也可以持續(xù)定位
[locationManager requestAlwaysAuthorization];
請求方法二選一另患。接著在CLLocationManagerDelegate代理里面實(shí)現(xiàn)
// 當(dāng)此應(yīng)用程序的授權(quán)狀態(tài)更改時調(diào)用
- (void)locationManager:(CLLocationManager *)manager didChangeAuthorizationStatus:(CLAuthorizationStatus)status {
}
方法,返回的status就是當(dāng)前用的選擇的狀態(tài)了蛾绎。需要注意的是柴淘,如果CLLocationManager對象被釋放了,那么彈窗也會消失秘通,所以可以把CLLocationManager對象變成屬性或者成員變量。
2敛熬、消息通知
推送通知需要使用的框架是#import <UserNotifications/UserNotifications.h> // 通知框架
權(quán)限狀態(tài)獲取方法是:
此時要區(qū)分系統(tǒng)版本獲取肺稀,在iOS10之后使用:
[[UNUserNotificationCenter currentNotificationCenter] getNotificationSettingsWithCompletionHandler:^(UNNotificationSettings * _Nonnull settings) {
// 獲取狀態(tài)
UNAuthorizationStatus authorizationStatus = settings.authorizationStatus;
}];
獲取到的狀態(tài)有:
// 該枚舉在iOS 10 之后才能使用
typedef NS_ENUM(NSInteger, UNAuthorizationStatus) {
UNAuthorizationStatusNotDetermined = 0, // 還未授權(quán)
UNAuthorizationStatusDenied, // 被拒絕
UNAuthorizationStatusAuthorized // 用戶允許
} __IOS_AVAILABLE(10.0) __TVOS_AVAILABLE(10.0) __WATCHOS_AVAILABLE(3.0);
請求權(quán)限通知的API方法:
// User authorization is required for applications to notify the user using UNUserNotificationCenter via both local and remote notifications.
- (void)requestAuthorizationWithOptions:(UNAuthorizationOptions)options completionHandler:(void (^)(BOOL granted, NSError *__nullable error))completionHandler;
// 使用方法
UNUserNotificationCenter * center = [UNUserNotificationCenter currentNotificationCenter];
[center requestAuthorizationWithOptions:(UNAuthorizationOptionAlert | UNAuthorizationOptionBadge | UNAuthorizationOptionSound) completionHandler:^(BOOL granted, NSError * _Nullable error) {
// granted 代表允許與否
dispatch_async(dispatch_get_main_queue(), ^{
// 回到主線程
});
}];
值得注意的是应民,此時block回調(diào)是在任意線程中的话原,所以需要回到主線程內(nèi)處理其他代碼
UNAuthorizationOptions枚舉是:
typedef NS_OPTIONS(NSUInteger, UNAuthorizationOptions) {
UNAuthorizationOptionBadge = (1 << 0), // 角標(biāo)
UNAuthorizationOptionSound = (1 << 1), // 聲音
UNAuthorizationOptionAlert = (1 << 2), // 彈窗
UNAuthorizationOptionCarPlay = (1 << 3), // 車載
} __IOS_AVAILABLE(10.0) __TVOS_AVAILABLE(10.0) __WATCHOS_AVAILABLE(3.0);
在iOS10之前使用
BOOL result = [[UIApplication sharedApplication] isRegisteredForRemoteNotifications];
// result 就是授權(quán)狀態(tài) ...
3、錄音權(quán)限(info.plist需要添加MicrophoneUsageDescription)
錄音權(quán)限就要使用#import <AVFoundation/AVFoundation.h> // 音視頻框架
請求錄音權(quán)限通知的API方法:
AVAudioSession * audioSession = [AVAudioSession sharedInstance];
[audioSession requestRecordPermission:^(BOOL granted) {
// granted 代表允許與否
dispatch_async(dispatch_get_main_queue(), ^{
// 回到主線程
});
}];
值得注意的是诲锹,此時block回調(diào)是在任意線程中的繁仁,所以需要回到主線程內(nèi)處理其他代碼
4、相機(jī)權(quán)限(info.plist需要添加CameraUsageDescription)
相機(jī)權(quán)限就要使用#import <AVFoundation/AVFoundation.h> // 音視頻框架
獲取當(dāng)前權(quán)限狀態(tài)API:
AVAuthorizationStatus cameraAuthorizationStatus = [AVCaptureDevice authorizationStatusForMediaType:AVMediaTypeVideo];
獲取到的狀態(tài)有:
typedef NS_ENUM(NSInteger, AVAuthorizationStatus) {
AVAuthorizationStatusNotDetermined = 0, // 未授權(quán)归园,需要調(diào)用方法觸發(fā)授權(quán)
AVAuthorizationStatusRestricted = 1, // 已被限制黄虱,例如家長控制等等
AVAuthorizationStatusDenied = 2, // 已被拒絕
AVAuthorizationStatusAuthorized = 3, // 已允許
} NS_AVAILABLE_IOS(7_0) __TVOS_PROHIBITED;
請求相機(jī)權(quán)限通知的API方法:
[AVCaptureDevice requestAccessForMediaType:AVMediaTypeVideo completionHandler:^(BOOL granted) {
// granted 代表允許與否
dispatch_async(dispatch_get_main_queue(), ^{
// 回到主線程
});
}];
值得注意的是,此時block回調(diào)是在任意線程中的庸诱,所以需要回到主線程內(nèi)處理其他代碼
5捻浦、相冊權(quán)限(info.plist需要添加NSPhotoLibraryUsageDescription)
需要查看手機(jī)相冊需要使用 iOS8.0之前使用#import <AssetsLibrary/AssetsLibrary.h> 和 iOS8.0之后使用 #import <Photos/Photos.h>
獲取當(dāng)前相冊權(quán)限狀態(tài)API晤揣,在iOS8.0之后使用:
PHAuthorizationStatus PHAssetsAuthorizationStatus = [PHPhotoLibrary authorizationStatus];
獲取到的狀態(tài)有:
typedef NS_ENUM(NSInteger, PHAuthorizationStatus) {
PHAuthorizationStatusNotDetermined = 0, // 還未授權(quán),需要觸發(fā)授權(quán)方法
PHAuthorizationStatusRestricted, // 已被限制朱灿,例如家長控制等等
PHAuthorizationStatusDenied, // 已被拒絕
PHAuthorizationStatusAuthorized // 已允許
} PHOTOS_AVAILABLE_IOS_TVOS(8_0, 10_0);
請求相冊權(quán)限通知的API方法:
[PHPhotoLibrary requestAuthorization:^(PHAuthorizationStatus status) {
dispatch_async(dispatch_get_main_queue(), ^{
// 回到主線程操作
});
}];
值得注意的是昧识,此時block回調(diào)是在任意線程中的,所以需要回到主線程內(nèi)處理其他代碼
iOS 8.0之前使用API:
ALAuthorizationStatus ALAssetsAuthorizationStatus = [ALAssetsLibrary authorizationStatus];
獲取到的狀態(tài)有:
typedef NS_ENUM(NSInteger, ALAuthorizationStatus) {
ALAuthorizationStatusNotDetermined , // 還未授權(quán)盗扒,需要觸發(fā)授權(quán)方法
ALAuthorizationStatusRestricted , // 已被限制跪楞,例如家長控制等等
ALAuthorizationStatusDenied , // 已被拒絕
ALAuthorizationStatusAuthorized // 已允許
} NS_DEPRECATED_IOS(6_0, 9_0, "Use PHAuthorizationStatus in the Photos framework instead");
當(dāng)獲取到的狀態(tài)是ALAuthorizationStatusNotDetermined需要觸發(fā)授權(quán)方法,授權(quán)API是:
[ALAssetsLibrary alloc] init] enumerateGroupsWithTypes:ALAssetsGroupAll usingBlock:^(ALAssetsGroup *group, BOOL *stop) {
dispatch_async(dispatch_get_main_queue(), ^{
// 回到主線程
});
} failureBlock:^(NSError *error) {
dispatch_async(dispatch_get_main_queue(), ^{
// 回到主線程
});
}];
值得注意的是侣灶,此時block回調(diào)是在任意線程中的甸祭,所以需要回到主線程內(nèi)處理其他代碼
6、通訊錄權(quán)限(info.plist需要添加ContactsUsageDescription)
需要查看通訊錄權(quán)限需要使用 iOS9.0之前使用#import <AddressBook/AddressBook.h> 和 iOS9.0之后使用 #import <Contacts/Contacts.h>
獲取通訊錄權(quán)限狀態(tài)API炫隶,在iOS9.0之后使用:
CNAuthorizationStatus authorizationStatus = [CNContactStore authorizationStatusForEntityType:CNEntityTypeContacts];
獲取到的狀態(tài)有:
typedef NS_ENUM(NSInteger, CNAuthorizationStatus) {
CNAuthorizationStatusNotDetermined = 0, // 還未授權(quán)淋叶,需要觸發(fā)授權(quán)方法
CNAuthorizationStatusRestricted, // 已被限制,例如家長控制等等
CNAuthorizationStatusDenied, // 已被拒絕
CNAuthorizationStatusAuthorized // 已允許
} NS_ENUM_AVAILABLE(10_11, 9_0);
當(dāng)獲取到的狀態(tài)是CNAuthorizationStatusNotDetermined需要觸發(fā)授權(quán)方法伪阶,授權(quán)API是:
[[[CNContactStore alloc] init] requestAccessForEntityType:CNEntityTypeContacts completionHandler:^(BOOL granted, NSError * _Nullable error) {
dispatch_async(dispatch_get_main_queue(), ^{
// 回到主線程操作
});
}];
值得注意的是煞檩,此時block回調(diào)是在任意線程中的,所以需要回到主線程內(nèi)處理其他代碼
iOS 9.0之前使用API:
ABAuthorizationStatus authorizationStatus = ABAddressBookGetAuthorizationStatus();
獲取到的狀態(tài)有:
typedef CF_ENUM(CFIndex, ABAuthorizationStatus) {
kABAuthorizationStatusNotDetermined = 0, // 還未授權(quán)栅贴,需要觸發(fā)授權(quán)方法
kABAuthorizationStatusRestricted, // 已被限制斟湃,例如家長控制等等
kABAuthorizationStatusDenied, // 已被拒絕
kABAuthorizationStatusAuthorized // 已允許
} AB_DEPRECATED("use CNAuthorizationStatus");
當(dāng)獲取到的狀態(tài)是kABAuthorizationStatusNotDetermined時,需要觸發(fā)授權(quán)方法檐薯,授權(quán)API是:
ABAddressBookRef bookref = ABAddressBookCreateWithOptions(NULL, NULL);
ABAddressBookRequestAccessWithCompletion(bookref, ^(bool granted, CFErrorRef error) {
// 這里granted是用戶點(diǎn)擊后的狀態(tài)
});
7凝赛、日歷權(quán)限 + 日歷提醒事件權(quán)限 (info.plist需要添加CalendarsUsageDescription + RemindersUsageDescription)
需要查看日歷權(quán)限需要使用 #import <EventKit/EventKit.h>
獲取當(dāng)前權(quán)限狀態(tài)API是:
// 獲取日歷權(quán)限
EKAuthorizationStatus status = [EKEventStore authorizationStatusForEntityType:EKEntityTypeEvent];
// 獲取提醒事件權(quán)限
EKAuthorizationStatus status = [EKEventStore authorizationStatusForEntityType:EKEntityTypeReminder];
獲取到的狀態(tài)有:
typedef NS_ENUM(NSInteger, EKAuthorizationStatus) {
EKAuthorizationStatusNotDetermined = 0, // 還未授權(quán),需要觸發(fā)授權(quán)方法
EKAuthorizationStatusRestricted, // 已被限制坛缕,例如家長控制等等
EKAuthorizationStatusDenied, // 已被拒絕
EKAuthorizationStatusAuthorized, // 已允許
} NS_AVAILABLE(10_9, 6_0);
當(dāng)獲取到的狀態(tài)是EKAuthorizationStatusNotDetermined時墓猎,需要觸發(fā)授權(quán)方法,授權(quán)API是:
// 觸發(fā)日歷權(quán)限API
[[[EKEventStore alloc] init] requestAccessToEntityType:EKEntityTypeEvent completion:^(BOOL granted, NSError * _Nullable error) {
dispatch_async(dispatch_get_main_queue(), ^{
// 需要回到主線程操作
});
}];
// 觸發(fā)提醒事件權(quán)限API
[[[EKEventStore alloc] init] requestAccessToEntityType:EKEntityTypeReminder completion:^(BOOL granted, NSError * _Nullable error) {
dispatch_async(dispatch_get_main_queue(), ^{
// 需要回到主線程操作
});
}];
值得注意的是赚楚,此時block回調(diào)是在任意線程中的毙沾,所以需要回到主線程內(nèi)處理其他代碼
8、語音識別功能權(quán)限 (info.plist需要添加SpeechRecognitionUsageDescription)
語音識別功能api接口只有在iOS10之后才有宠页,所以最低都要從iOS10開始使用
需要使用語音識別功能需要使用 #import <Speech/Speech.h>
獲取當(dāng)前權(quán)限狀態(tài)API是:
SFSpeechRecognizerAuthorizationStatus status = [SFSpeechRecognizer authorizationStatus];
獲取到的狀態(tài)有:
typedef NS_ENUM(NSInteger, SFSpeechRecognizerAuthorizationStatus) {
SFSpeechRecognizerAuthorizationStatusNotDetermined, // 還未授權(quán)左胞,需要觸發(fā)授權(quán)方法
SFSpeechRecognizerAuthorizationStatusDenied, // 已被拒絕
SFSpeechRecognizerAuthorizationStatusRestricted, // 已被限制,例如家長控制等等
SFSpeechRecognizerAuthorizationStatusAuthorized, // 已允許
} API_AVAILABLE(ios(10.0));
當(dāng)獲取到的狀態(tài)是SFSpeechRecognizerAuthorizationStatusNotDetermined時举户,需要觸發(fā)授權(quán)方法烤宙,授權(quán)API是:
[SFSpeechRecognizer requestAuthorization:^(SFSpeechRecognizerAuthorizationStatus status) {
dispatch_async(dispatch_get_main_queue(), ^{
// 回到主線程操作
});
}];
值得注意的是,此時block回調(diào)是在任意線程中的俭嘁,所以需要回到主線程內(nèi)處理其他代碼
最后添加上所有權(quán)限key的代碼
<key>NSCalendarsUsageDescription</key>
<string>日歷</string>
<key>NSCameraUsageDescription</key>
<string>需要獲取您的攝像頭信息</string>
<key>NSContactsUsageDescription</key>
<string>需要獲取您的通訊錄權(quán)限</string>
<key>NSLocationAlwaysUsageDescription</key>
<string>“始終”定位權(quán)限</string>
<key>NSLocationWhenInUseUsageDescription</key>
<string>“使用應(yīng)用期間”定位權(quán)限</string>
<key>NSMicrophoneUsageDescription</key>
<string>需要獲取您的麥克風(fēng)權(quán)限</string>
<key>NSPhotoLibraryUsageDescription</key>
<string>需要獲取您的相冊信息</string>
<key>NSRemindersUsageDescription</key>
<string>提醒事項</string>
<key>NSSpeechRecognitionUsageDescription</key>
<string>語音識別權(quán)限</string>
描述文字一定要說清楚作用躺枕,不然會被拒絕,拒絕,拒絕屯远,當(dāng)然這還要看審核人員的心情了蔓姚。當(dāng)事人已經(jīng)被拒絕過了