iOS 系統(tǒng)權(quán)限檢測功能

自從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)被拒絕過了

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市慨丐,隨后出現(xiàn)的幾起案子坡脐,更是在濱河造成了極大的恐慌,老刑警劉巖房揭,帶你破解...
    沈念sama閱讀 221,820評論 6 515
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件备闲,死亡現(xiàn)場離奇詭異,居然都是意外死亡捅暴,警方通過查閱死者的電腦和手機(jī)恬砂,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,648評論 3 399
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來蓬痒,“玉大人泻骤,你說我怎么就攤上這事∥嗌荩” “怎么了狱掂?”我有些...
    開封第一講書人閱讀 168,324評論 0 360
  • 文/不壞的土叔 我叫張陵,是天一觀的道長亲轨。 經(jīng)常有香客問我趋惨,道長,這世上最難降的妖魔是什么惦蚊? 我笑而不...
    開封第一講書人閱讀 59,714評論 1 297
  • 正文 為了忘掉前任器虾,我火速辦了婚禮,結(jié)果婚禮上蹦锋,老公的妹妹穿的比我還像新娘兆沙。我一直安慰自己,他們只是感情好莉掂,可當(dāng)我...
    茶點(diǎn)故事閱讀 68,724評論 6 397
  • 文/花漫 我一把揭開白布葛圃。 她就那樣靜靜地躺著,像睡著了一般巫湘。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上昏鹃,一...
    開封第一講書人閱讀 52,328評論 1 310
  • 那天尚氛,我揣著相機(jī)與錄音,去河邊找鬼洞渤。 笑死阅嘶,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播讯柔,決...
    沈念sama閱讀 40,897評論 3 421
  • 文/蒼蘭香墨 我猛地睜開眼抡蛙,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了魂迄?” 一聲冷哼從身側(cè)響起粗截,我...
    開封第一講書人閱讀 39,804評論 0 276
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎捣炬,沒想到半個月后熊昌,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 46,345評論 1 318
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡湿酸,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,431評論 3 340
  • 正文 我和宋清朗相戀三年婿屹,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片推溃。...
    茶點(diǎn)故事閱讀 40,561評論 1 352
  • 序言:一個原本活蹦亂跳的男人離奇死亡昂利,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出铁坎,到底是詐尸還是另有隱情蜂奸,我是刑警寧澤,帶...
    沈念sama閱讀 36,238評論 5 350
  • 正文 年R本政府宣布厢呵,位于F島的核電站窝撵,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏襟铭。R本人自食惡果不足惜碌奉,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,928評論 3 334
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望寒砖。 院中可真熱鬧赐劣,春花似錦、人聲如沸哩都。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,417評論 0 24
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽漠嵌。三九已至咐汞,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間儒鹿,已是汗流浹背化撕。 一陣腳步聲響...
    開封第一講書人閱讀 33,528評論 1 272
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留约炎,地道東北人植阴。 一個月前我還...
    沈念sama閱讀 48,983評論 3 376
  • 正文 我出身青樓蟹瘾,卻偏偏與公主長得像,于是被迫代替她去往敵國和親掠手。 傳聞我的和親對象是個殘疾皇子憾朴,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,573評論 2 359