iOS開發中權限問題:
- APP開發避免不開系統權限的問題,如何在APP以更加友好的方式向用戶展示系統權限,似乎也是開發過程中值得深思的一件事;
-
那如何提高APP獲取iOS系統權限的通過率呢?有以下幾種方式:1.在用戶打開APP時就向用戶請求權限;2.告知用戶授權權限后能夠獲得好處之后,再向用戶請求權限;3.在絕對必要的情況下才向用戶請求權限,例如:用戶訪問照片庫時請求訪問系統相冊權限;4.在展示系統權限的對話框前,先向用戶顯示自定義的對話框,若用戶選擇不允許,默認無操作,若用戶選擇允許,再展示系統對話框。
-
上述情況在開發過程中是經常遇到的,不同方式的選擇會影響最后用戶交互體驗。這一點感悟正是源於上一周工作遇到的問題:適配iOS10,如何獲取應用聯網權限用以管理系統對話框的顯示管理。當我把這個問題解決后,感覺有必要將常用的iOS系統權限做一個總結,以便后用。
權限分類
- 聯網權限
- 相冊權限
- 相機、麥克風權限
- 定位權限
- 推送權限
- 通訊錄權限
- 日歷、備忘錄權限
聯網權限
- 引入頭文件 @import CoreTelephony;
- 檢查應用是否有聯網功能
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; }
-
應用啟動后,獲取應用中是否有聯網權限
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; }; };
相冊權限--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]];
還有藍牙...等
