寫在前面
-
APP開發避免不開系統權限的問題,如何在APP以更加友好的方式向用戶展示系統權限,似乎也是開發過程中值得深思的一件事;
-
那如何提高APP獲取iOS系統權限的通過率呢?有以下幾種方式:
1.在用戶打開APP時就向用戶請求權限;
2.告知用戶授權權限後能夠獲得好處之後,再向用戶請求權限;
3.在絕對必要的情況下才向用戶請求權限,例如:用戶訪問照片庫時請求訪問系統相冊權限;
4.在展示系統權限的對話框前,先向用戶顯示自定義的對話框,若用戶選擇不允許,默認無操作,若用戶選擇允許,再展示系統對話框。 -
上述情況在開發過程中是經常遇到的,不同方式的選擇會影響最後用戶交互體驗。這一點感悟正是源於上一週工作遇到的問題:適配iOS10,如何獲取應用聯網權限用以管理系統對話框的顯示管理。當我把這個問題解決後,感覺有必要將常用的iOS系統權限做一個總結,以便後用。
權限分類
- 聯網權限
- 相冊權限
- 相機、麥克風權限
- 定位權限
- 推送權限
- 通訊錄權限
- 日曆、備忘錄權限
聯網權限
-
引入頭文件 @import CoreTelephony;
-
應用啓動後,檢測應用中是否有聯網權限
CTCellularData *cellularData = [[CTCellularData alloc]init]; cellularData.cellularDataRestrictionDidUpdateNotifier = ^(CTCellularDataRestrictedState state){ //獲取聯網狀態 switch (state) { case kCTCellularDataRestricted: NSLog(@"Restricrted"); break; case kCTCellularDataNotRestricted: NSLog(@"Not Restricted"); break; case kCTCellularDataRestrictedStateUnknown: NSLog(@"Unknown"); break; default: break; }; };
-
查詢應用是否有聯網功能
CTCellularData *cellularData = [[CTCellularData alloc]init]; CTCellularDataRestrictedState state = cellularData.restrictedState; switch (state) { case kCTCellularDataRestricted: NSLog(@"Restricrted"); break; case kCTCellularDataNotRestricted: NSLog(@"Not Restricted"); break; case kCTCellularDataRestrictedStateUnknown: NSLog(@"Unknown"); break; default: break; }
相冊權限--iOS 9.0之前
-
導入頭文件@import AssetsLibrary;
-
檢查是否有相冊權限
ALAuthorizationStatus status = [ALAssetsLibrary authorizationStatus]; switch (status) { case ALAuthorizationStatusAuthorized: NSLog(@"Authorized"); break; case ALAuthorizationStatusDenied: NSLog(@"Denied"); break; case ALAuthorizationStatusNotDetermined: NSLog(@"not Determined"); break; case ALAuthorizationStatusRestricted: NSLog(@"Restricted"); break; default: break; }
相冊權限--iOS 8.0之後
-
導入頭文件@import Photos;
-
檢查是否有相冊權限
PHAuthorizationStatus photoAuthorStatus = [PHPhotoLibrary authorizationStatus]; switch (photoAuthorStatus) { case PHAuthorizationStatusAuthorized: NSLog(@"Authorized"); break; case PHAuthorizationStatusDenied: NSLog(@"Denied"); break; case PHAuthorizationStatusNotDetermined: NSLog(@"not Determined"); break; case PHAuthorizationStatusRestricted: NSLog(@"Restricted"); break; default: break; }
獲取相冊權限
[PHPhotoLibrary requestAuthorization:^(PHAuthorizationStatus status) {
if (status == PHAuthorizationStatusAuthorized) {
NSLog(@"Authorized");
}else{
NSLog(@"Denied or Restricted");
}
}];
相機和麥克風權限
-
導入頭文件@import AVFoundation;
-
檢查是否有相機或麥克風權限
AVAuthorizationStatus AVstatus = [AVCaptureDevice authorizationStatusForMediaType:AVMediaTypeVideo];//相機權限 AVAuthorizationStatus AVstatus = [AVCaptureDevice authorizationStatusForMediaType:AVMediaTypeAudio];//麥克風權限 switch (AVstatus) { case AVAuthorizationStatusAuthorized: NSLog(@"Authorized"); break; case AVAuthorizationStatusDenied: NSLog(@"Denied"); break; case AVAuthorizationStatusNotDetermined: NSLog(@"not Determined"); break; case AVAuthorizationStatusRestricted: NSLog(@"Restricted"); break; default: break; }
-
獲取相機或麥克風權限
[AVCaptureDevice requestAccessForMediaType:AVMediaTypeVideo completionHandler:^(BOOL granted) {//相機權限 if (granted) { NSLog(@"Authorized"); }else{ NSLog(@"Denied or Restricted"); } }]; [AVCaptureDevice requestAccessForMediaType:AVMediaTypeAudio completionHandler:^(BOOL granted) {//麥克風權限 if (granted) { NSLog(@"Authorized"); }else{ NSLog(@"Denied or Restricted"); } }];
定位權限
- 導入頭文件@import CoreLocation;
- 由於iOS8.0之後定位方法的改變,需要在info.plist中進行配置;
配置文件
-
檢查是否有定位權限
BOOL isLocation = [CLLocationManager locationServicesEnabled]; if (!isLocation) { NSLog(@"not turn on the location"); } CLAuthorizationStatus CLstatus = [CLLocationManager authorizationStatus]; switch (CLstatus) { case kCLAuthorizationStatusAuthorizedAlways: NSLog(@"Always Authorized"); break; case kCLAuthorizationStatusAuthorizedWhenInUse: NSLog(@"AuthorizedWhenInUse"); break; case kCLAuthorizationStatusDenied: NSLog(@"Denied"); break; case kCLAuthorizationStatusNotDetermined: NSLog(@"not Determined"); break; case kCLAuthorizationStatusRestricted: NSLog(@"Restricted"); break; default: break; }
-
獲取定位權限
CLLocationManager *manager = [[CLLocationManager alloc] init]; [manager requestAlwaysAuthorization];//一直獲取定位信息 [manager requestWhenInUseAuthorization];//使用的時候獲取定位信息
-
在代理方法中查看權限是否改變
- (void)locationManager:(CLLocationManager *)manager didChangeAuthorizationStatus:(CLAuthorizationStatus)status{ switch (status) { case kCLAuthorizationStatusAuthorizedAlways: NSLog(@"Always Authorized"); break; case kCLAuthorizationStatusAuthorizedWhenInUse: NSLog(@"AuthorizedWhenInUse"); break; case kCLAuthorizationStatusDenied: NSLog(@"Denied"); break; case kCLAuthorizationStatusNotDetermined: NSLog(@"not Determined"); break; case kCLAuthorizationStatusRestricted: NSLog(@"Restricted"); break; default: break; } }
推送權限
-
檢查是否有通訊權限
UIUserNotificationSettings *settings = [[UIApplication sharedApplication] currentUserNotificationSettings]; switch (settings.types) { case UIUserNotificationTypeNone: NSLog(@"None"); break; case UIUserNotificationTypeAlert: NSLog(@"Alert Notification"); break; case UIUserNotificationTypeBadge: NSLog(@"Badge Notification"); break; case UIUserNotificationTypeSound: NSLog(@"sound Notification'"); break; default: break; }
-
獲取推送權限
UIUserNotificationSettings *setting = [UIUserNotificationSettings settingsForTypes:UIUserNotificationTypeSound | UIUserNotificationTypeAlert | UIUserNotificationTypeBadge categories:nil]; [[UIApplication sharedApplication] registerUserNotificationSettings:setting];
通訊錄權限
iOS9.0之前
-
導入頭文件 @import AddressBook;
-
檢查是否有通訊錄權限
ABAuthorizationStatus ABstatus = ABAddressBookGetAuthorizationStatus(); switch (ABstatus) { case kABAuthorizationStatusAuthorized: NSLog(@"Authorized"); break; case kABAuthorizationStatusDenied: NSLog(@"Denied'"); break; case kABAuthorizationStatusNotDetermined: NSLog(@"not Determined"); break; case kABAuthorizationStatusRestricted: NSLog(@"Restricted"); break; default: break; }
-
獲取通訊錄權限
ABAddressBookRef addressBook = ABAddressBookCreateWithOptions(NULL, NULL); ABAddressBookRequestAccessWithCompletion(addressBook, ^(bool granted, CFErrorRef error) { if (granted) { NSLog(@"Authorized"); CFRelease(addressBook); }else{ NSLog(@"Denied or Restricted"); } });
iOS9.0及以後
- 導入頭文件 @import Contacts;
- 檢查是否有通訊錄權限
CNAuthorizationStatus status = [CNContactStore authorizationStatusForEntityType:CNEntityTypeContacts];
switch (status) {
case CNAuthorizationStatusAuthorized:
{
NSLog(@"Authorized:");
}
break;
case CNAuthorizationStatusDenied:{
NSLog(@"Denied");
}
break;
case CNAuthorizationStatusRestricted:{
NSLog(@"Restricted");
}
break;
case CNAuthorizationStatusNotDetermined:{
NSLog(@"NotDetermined");
}
break;
}
- 獲取通訊錄權限
CNContactStore *contactStore = [[CNContactStore alloc] init];
[contactStore requestAccessForEntityType:CNEntityTypeContacts completionHandler:^(BOOL granted, NSError * _Nullable error) {
if (granted) {
NSLog(@"Authorized");
}else{
NSLog(@"Denied or Restricted");
}
}];
日曆、備忘錄權限
-
導入頭文件
-
檢查是否有日曆或者備忘錄權限
typedef NS_ENUM(NSUInteger, EKEntityType) { EKEntityTypeEvent,//日曆 EKEntityTypeReminder //備忘 };
-
EKAuthorizationStatus EKstatus = [EKEventStore authorizationStatusForEntityType:EKEntityTypeEvent]; switch (EKstatus) { case EKAuthorizationStatusAuthorized: NSLog(@"Authorized"); break; case EKAuthorizationStatusDenied: NSLog(@"Denied'"); break; case EKAuthorizationStatusNotDetermined: NSLog(@"not Determined"); break; case EKAuthorizationStatusRestricted: NSLog(@"Restricted"); break; default: break; }
-
獲取日曆或備忘錄權限
EKEventStore *store = [[EKEventStore alloc]init]; [store requestAccessToEntityType:EKEntityTypeEvent completion:^(BOOL granted, NSError * _Nullable error) { if (granted) { NSLog(@"Authorized"); }else{ NSLog(@"Denied or Restricted"); } }];
最後一點
-
素有獲取權限的方法,多用於用戶第一次操作應用,iOS 8.0之後,將這些設置都整合在一起,並且可以開啓或關閉相應的權限。所有的權限都可以通過下面的方法打開:
[[UIApplication sharedApplication] openURL:[NSURL URLWithString:UIApplicationOpenSettingsURLString]];