背景
iOS的安全機(jī)制——沙盒限制了應(yīng)用程序執(zhí)行各種操作的權(quán)限。沙盒實(shí)際就是程序的系統(tǒng)文件目錄,非代碼文件都在此保存梁剔,例如圖片驾诈、圖標(biāo)、視頻蒋川、plist文件、文本文件,每個(gè)iOS程序只能訪問(wèn)自己沙盒中的東西跟啤,訪問(wèn)其他沙盒需要權(quán)限,它相對(duì)封閉唉锌、獨(dú)立隅肥,使得iOS環(huán)境較為穩(wěn)定。
iOS系統(tǒng)自iOS7.0之后袄简,不同階段的系統(tǒng)版本的權(quán)限特征或多或少都有所差異腥放。若軟件沒(méi)有做好權(quán)限相應(yīng)的限制適配,在提交APP Store審核時(shí)會(huì)被拒絕上線绿语。例如在iOS10系統(tǒng)中秃症,如果沒(méi)有根據(jù)更新的權(quán)限要求在info.plist中進(jìn)行聲明而訪問(wèn)了隱私數(shù)據(jù),在Xcode8中打開編譯的話吕粹,會(huì)發(fā)生crash.
權(quán)限機(jī)制
Android系統(tǒng)對(duì)權(quán)限的隱私危害性進(jìn)行三級(jí)劃分种柑,分為普通權(quán)限、特殊權(quán)限匹耕、危險(xiǎn)權(quán)限聚请。而iOS系統(tǒng)沒(méi)有這些分類,基本采用第一次使用某功能就請(qǐng)求權(quán)限泌神,之后除非在隱私中關(guān)閉該應(yīng)用的該權(quán)限良漱,否則該程序?qū)⒁恢睋碛性摍?quán)限舞虱。
基礎(chǔ)知識(shí)
iOS13.1.1所有的權(quán)限:參照此圖,iOS應(yīng)用申請(qǐng)的主要權(quán)限有:
- 定位服務(wù)
- 通訊錄
- 日歷
- 提醒事項(xiàng)
- 照片
- 藍(lán)牙
- 麥克風(fēng)
- 語(yǔ)音識(shí)別(iOS10)
- 相機(jī)
- 健康(iOS8.0)
- Home kit(iOS8.0)
- 媒體與Apple Music(iOS9.0)
- 文件與文件夾(iOS12.0)
- 運(yùn)動(dòng)與健身
權(quán)限的狀態(tài):
- 用戶從未進(jìn)行過(guò)授權(quán)等處理母市,首次訪問(wèn)相應(yīng)內(nèi)容會(huì)提示用戶進(jìn)行授權(quán)
- 已授權(quán)
- 拒絕
- 應(yīng)用沒(méi)有相關(guān)權(quán)限矾兜,且當(dāng)前用戶無(wú)法改變這個(gè)權(quán)限,比如:家長(zhǎng)控制
- 硬件等不支持
操作:
- 檢查授權(quán)狀態(tài)
-
請(qǐng)求授權(quán)
具體代碼:
- 定位服務(wù)
-
獲取狀態(tài)
BOOL enable = [CLLocationManager locationServicesEnabled];//是否可用 NSInteger state = [CLLocationManager authorizationStatus];//授權(quán)狀態(tài)
-
申請(qǐng)權(quán)限
self.locationManager = [[CLLocationManager alloc] init]; self.locationManager.delegate = self; [self.locationManager requestAlwaysAuthorization]; [self.locationManager requestWhenInUseAuthorization];
-
- 通訊錄
-
獲取狀態(tài)
CNAuthorizationStatus status = [CNContactStore authorizationStatusForEntityType:CNEntityTypeContacts];
-
申請(qǐng)權(quán)限
CNContactStore *contactStore = [[CNContactStore alloc] init]; [contactStore requestAccessForEntityType:CNEntityTypeContacts completionHandler:^(BOOL granted, NSError * _Nullable error) { }];
-
- 日歷
-
獲取狀態(tài)
EKAuthorizationStatus status = [EKEventStore authorizationStatusForEntityType:EKEntityTypeEvent];
-
申請(qǐng)權(quán)限
EKEventStore *store = [[EKEventStore alloc] init]; [store requestAccessToEntityType:EKEntityTypeEvent completion:^(BOOL granted, NSError * _Nullable error) { }];
-
- 提醒事項(xiàng)
-
獲取狀態(tài)
EKAuthorizationStatus status = [EKEventStore authorizationStatusForEntityType:EKEntityTypeReminder];
-
申請(qǐng)權(quán)限
EKEventStore *store = [[EKEventStore alloc] init]; [store requestAccessToEntityType:EKEntityTypeReminder completion:^(BOOL granted, NSError * _Nullable error) { }];
-
- 照片
-
獲取狀態(tài)
if ([UIImagePickerController isSourceTypeAvailable:UIImagePickerControllerSourceTypePhotoLibrary]) { if (_isiOS8_Or_Later_) { PHAuthorizationStatus status = [PHPhotoLibrary authorizationStatus]; } else { // iOS7 - iOS8 ALAuthorizationStatus status = [ALAssetsLibrary authorizationStatus]; } } else { NSLog(@"相冊(cè)不可用患久!"); }
-
申請(qǐng)權(quán)限
if (_isiOS8_Or_Later_) { [PHPhotoLibrary requestAuthorization:^(PHAuthorizationStatus status) { }]; } else { ALAssetsLibrary *assetLibrary = [[ALAssetsLibrary alloc] init]; [assetLibrary enumerateGroupsWithTypes:ALAssetsGroupAll usingBlock:^(ALAssetsGroup *group, BOOL *stop) { } failureBlock:^(NSError *error) { }]; }
-
- 藍(lán)牙
-
獲取狀態(tài)
self.cbCentralManager = [[CBCentralManager alloc] initWithDelegate:self queue:nil]; #pragma mark - CBCentralManagerDelegate - (void)centralManagerDidUpdateState:(CBCentralManager *)central{ CBManagerState state = central.state; } }
申請(qǐng)權(quán)限
-
- 麥克風(fēng)
-
獲取狀態(tài)
AVAuthorizationStatus status = [AVCaptureDevice authorizationStatusForMediaType:AVMediaTypeAudio];
-
申請(qǐng)權(quán)限
[[AVAudioSession sharedInstance] requestRecordPermission:^(BOOL granted) { }];
-
- 語(yǔ)音識(shí)別
-
獲取狀態(tài)
SFSpeechRecognizerAuthorizationStatus status = [SFSpeechRecognizer authorizationStatus];
-
申請(qǐng)權(quán)限
[SFSpeechRecognizer requestAuthorization:^(SFSpeechRecognizerAuthorizationStatus status) { }];
-
- 相機(jī)
-
獲取狀態(tài)
if ([UIImagePickerController isSourceTypeAvailable:UIImagePickerControllerSourceTypeCamera]) { AVAuthorizationStatus status = [AVCaptureDevice authorizationStatusForMediaType:AVMediaTypeVideo]; }
-
申請(qǐng)權(quán)限
[AVCaptureDevice requestAccessForMediaType:AVMediaTypeVideo completionHandler:^(BOOL granted) { }];
-
- 健康
-
獲取狀態(tài)
if ([HKHealthStore isHealthDataAvailable]) { self.healthStore = [[HKHealthStore alloc] init]; // 以心率 HKQuantityTypeIdentifierHeartRate 為例子 HKQuantityType *heartRateType = [HKQuantityType quantityTypeForIdentifier:HKQuantityTypeIdentifierHeartRate]; HKAuthorizationStatus status = [self.healthStore authorizationStatusForType:heartRateType]; }else{ NSLog(@"unavailable"); // Health data is not avaliable on all device. }
-
申請(qǐng)權(quán)限
[self.healthStore requestAuthorizationToShareTypes:typeSet readTypes:typeSet completion:^(BOOL success, NSError * _Nullable error) { }];
-
- Home Kit
-
獲取狀態(tài)
self.homeManager = [[HMHomeManager alloc] init]; self.homeManager.delegate = self; #pragma mark - HMHomeManagerDelegate - (void)homeManagerDidUpdateHomes:(HMHomeManager *)manager{ if (manager.homes.count > 0) { } }
-
申請(qǐng)權(quán)限
[manager addHomeWithName:@"Test Home" completionHandler:^(HMHome * _Nullable home, NSError * _Nullable error) { }];
-
- 媒體與Apple Music(ios(9.3))
-
獲取狀態(tài)
SKCloudServiceAuthorizationStatus status = [SKCloudServiceController authorizationStatus];
-
申請(qǐng)權(quán)限
[SKCloudServiceController requestAuthorization:^(SKCloudServiceAuthorizationStatus status) { }];
-
- 文件與文件夾
-
拷貝模式:將文檔拷貝到自己項(xiàng)目中
//打開項(xiàng)目中的info.plist椅寺,添加“Document Types”鍵值 - (BOOL)application:(UIApplication *)app openURL:(NSURL *)url options:(NSDictionary<UIApplicationOpenURLOptionsKey,id> *)options{ }
-
存儲(chǔ)模式:將文檔存儲(chǔ)到“文件”中
//打開項(xiàng)目中的info.plist,添加“Supports Document Browser”鍵值 UIDocumentPickerViewController * controller = [[UIDocumentPickerViewController alloc]initWithDocumentTypes:[@""] inMode:UIDocumentPickerModeOpen]; controller.delegate = self; [self presentViewController:controller animated:YES completion:nil];
-
- 運(yùn)動(dòng)與健身
-
獲取狀態(tài)
if( [CMMotionActivityManager isActivityAvailable]){ CMAuthorizationStatus status = [CMMotionActivityManager authorizationStatus]; }
-
申請(qǐng)權(quán)限
self.cmManager = [[CMMotionActivityManager alloc] init]; self.motionActivityQueue = [[NSOperationQueue alloc] init]; [self.cmManager startActivityUpdatesToQueue:self.motionActivityQueue withHandler:^(CMMotionActivity *activity) { }];
-