一:打開相冊不提示用戶權限
問題描述:iOS11已經在plist文件中寫了相關權限設置,但是在使用UIImagePickerController打開相冊的時候卻不提示用戶選擇權限,有以下幾條情況:
- UIImagePickerController同樣的設置使用相機會有權限選擇提示,設置中也沒有關于相冊的設置;
- 項目中有用到TZImagePickerController的第三方庫多選照片,他在進入圖庫的時候就會有權限提示,設置中關于相冊的權限是:讀與寫;
- 將圖片保存進手機相冊會有權限提醒,設置中關于相冊的權限是:寫入;
帶著以上疑問我看了TZImagePickerController的源碼,發現他其實是在發現PHAuthorizationStatus為用戶未作出明確選擇的情況下自己主動請求了一次權限設置,代碼如下:
/// Return YES if Authorized 返回YES如果得到了授權
- (BOOL)authorizationStatusAuthorized {
NSInteger status = [self.class authorizationStatus];
if (status == 0) {
/**
* 當某些情況下AuthorizationStatus == AuthorizationStatusNotDetermined時,無法彈出系統首次使用的授權alertView,系統應用設置里亦沒有相冊的設置,此時將無法使用,故作以下操作,彈出系統首次使用的授權alertView
*/
[self requestAuthorizationWithCompletion:nil];
}
return status == 3;
}
+ (NSInteger)authorizationStatus {
if (iOS8Later) {
return [PHPhotoLibrary authorizationStatus];
} else {
return [ALAssetsLibrary authorizationStatus];
}
return NO;
}
- (void)requestAuthorizationWithCompletion:(void (^)())completion {
void (^callCompletionBlock)() = ^(){
dispatch_async(dispatch_get_main_queue(), ^{
if (completion) {
completion();
}
});
};
if (iOS8Later) {
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
[PHPhotoLibrary requestAuthorization:^(PHAuthorizationStatus status) {
callCompletionBlock();
}];
});
} else {
[self.assetLibrary enumerateGroupsWithTypes:ALAssetsGroupAll usingBlock:^(ALAssetsGroup *group, BOOL *stop) {
callCompletionBlock();
} failureBlock:^(NSError *error) {
callCompletionBlock();
}];
}
}
注:這里主動請求代碼權限獲得允許后不會跟系統的提示一樣直接跳到相冊,需要自己通過判斷確定,TZImagePickerController的處理辦法如下,當然也可以自己在權限設置的block里面設置
//下判斷權限,如果沒有權限就會先展示一個自定義的頁面,然后開始定時器來判斷是否已經獲取權限,如果獲取到權限則跳轉到選擇圖片頁面
if (![[TZImageManager manager] authorizationStatusAuthorized]) {
_tipLabel = [[UILabel alloc] init];
_tipLabel.frame = CGRectMake(8, 120, self.view.tz_width - 16, 60);
_tipLabel.textAlignment = NSTextAlignmentCenter;
_tipLabel.numberOfLines = 0;
_tipLabel.font = [UIFont systemFontOfSize:16];
_tipLabel.textColor = [UIColor blackColor];
NSDictionary *infoDict = [NSBundle mainBundle].localizedInfoDictionary;
if (!infoDict) {
infoDict = [NSBundle mainBundle].infoDictionary;
}
NSString *appName = [infoDict valueForKey:@"CFBundleDisplayName"];
if (!appName) appName = [infoDict valueForKey:@"CFBundleName"];
NSString *tipText = [NSString stringWithFormat:[NSBundle tz_localizedStringForKey:@"Allow %@ to access your album in \"Settings -> Privacy -> Photos\""],appName];
_tipLabel.text = tipText;
[self.view addSubview:_tipLabel];
if (iOS8Later) {
_settingBtn = [UIButton buttonWithType:UIButtonTypeSystem];
[_settingBtn setTitle:self.settingBtnTitleStr forState:UIControlStateNormal];
_settingBtn.frame = CGRectMake(0, 180, self.view.tz_width, 44);
_settingBtn.titleLabel.font = [UIFont systemFontOfSize:18];
[_settingBtn addTarget:self action:@selector(settingBtnClick) forControlEvents:UIControlEventTouchUpInside];
[self.view addSubview:_settingBtn];
}
//開啟定時器
_timer = [NSTimer scheduledTimerWithTimeInterval:0.2 target:self selector:@selector(observeAuthrizationStatusChange) userInfo:nil repeats:YES];
} else {
[self pushPhotoPickerVc];
}
- (void)observeAuthrizationStatusChange {
if ([[TZImageManager manager] authorizationStatusAuthorized]) {
[_tipLabel removeFromSuperview];
[_settingBtn removeFromSuperview];
[_timer invalidate];
_timer = nil;
[self pushPhotoPickerVc];
}
}
最后總結:打開相冊不在需要用戶授權,也就是說,默認對手機相冊擁有讀權限,因此在這里本人也就沒有做處理,檢查了手機上新更新的其他軟件,如果只需要訪問手機相冊也都沒有設置。等上線的時候看一下會不會被拒再來更新,如果已經有做過實驗的小伙伴謝謝告訴我一聲,不勝感激。