之前寫了一個仿Snapseed的ImagePicker,見Demo和之前的簡書文章,
之后發(fā)現(xiàn)有人說第一次未授權(quán)時collectionview會加載不出照片,發(fā)現(xiàn)沒有在合適時候調(diào)用權(quán)限管理。iOS10的這個權(quán)限管理是info.plist的一個鍵值,沒有回調(diào)方法。查詢photoskit方法里,發(fā)現(xiàn)有一個權(quán)限回調(diào)方法,就想封裝一個方法來友好的詢問用戶權(quán)限。
查詢文檔,相冊權(quán)限PHAuthorizationStatus枚舉類型有這么幾種。
typedef NS_ENUM(NSInteger, PHAuthorizationStatus) {
PHAuthorizationStatusNotDetermined = 0, // User has not yet made a choice with regards to this application 用戶未決定
PHAuthorizationStatusRestricted, // This application is not authorized to access photo data. 一般是家長權(quán)限之類的拒絕
// The user cannot change this application’s status, possibly due to active restrictions
// such as parental controls being in place.
PHAuthorizationStatusDenied, // User has explicitly denied this application access to photos data. 用戶拒絕
PHAuthorizationStatusAuthorized // User has authorized this application to access photos data. 用戶允許
} PHOTOS_AVAILABLE_IOS_TVOS(8_0, 10_0);
其中,我們不希望用戶去拒絕,達到PHAuthorizationStatusDenied這個狀態(tài),這樣的話用戶再要獲取權(quán)限就要到設置里的隱私里找到我們的應用再手動打開,而沒辦法在app內(nèi)去請求權(quán)限更改。那么我們希望暫時拒絕后的狀態(tài)應該是PHAuthorizationStatusNotDetermined的,思路就是提示一個alertviewcontroller去詢問,用戶取消則不去調(diào)用真正的詢問權(quán)限(相當于忽略),以便下次提醒在詢問。用戶同意則調(diào)用系統(tǒng)詢問權(quán)限,這時一般用戶也會再允許了。流程示意圖如下。

代碼很簡單,直接貼上來
- (void)showPermissionAlertInController{
UIAlertController *alert = [UIAlertController alertControllerWithTitle:nil message:@"需要你的圖庫的權(quán)限" preferredStyle:UIAlertControllerStyleAlert];
UIAlertAction *cancelAction = [UIAlertAction actionWithTitle:@"取消" style:UIAlertActionStyleCancel handler:^(UIAlertAction *action) {
//do something
}];
UIAlertAction *requestAction = [UIAlertAction actionWithTitle:@"同意" style:UIAlertActionStyleDefault handler:^(UIAlertAction *action) {
dispatch_async(dispatch_get_global_queue(0, 0), ^{
[PHPhotoLibrary requestAuthorization:^(PHAuthorizationStatus status) {
if (status == PHAuthorizationStatusAuthorized) {
NSLog(@"用戶同意授權(quán)相冊");
}else {
NSLog(@"用戶拒絕授權(quán)相冊");
}
dispatch_async(dispatch_get_main_queue(), ^{
//do something
});
}];
});
}];
[alert addAction:cancelAction];
[alert addAction:requestAction];
[self presentViewController:alert animated:YES completion:nil];
}
再在需要用到權(quán)限的地方加上判斷就好
if ([PHPhotoLibrary authorizationStatus] == PHAuthorizationStatusAuthorized)
后來發(fā)現(xiàn)如果調(diào)用選擇器時在外部改變了照片(增加,刪除)后collectionview不會改變,就研究了一下photoskit,發(fā)現(xiàn)有個- (void)photoLibraryDidChange:(PHChange *)changeInfo檢測相冊變動,但之前需要注冊為觀察者并實現(xiàn)協(xié)議
PHPhotoLibraryChangeObserver
- (void)viewDidLoad{
[super viewDidLoad];
[[PHPhotoLibrary sharedPhotoLibrary]registerChangeObserver:self];
//other code
}
- (void)dealloc{
[[PHPhotoLibrary sharedPhotoLibrary]unregisterChangeObserver:self];
}
然后實現(xiàn)方法,更新ui的話要在主線程里
- (void)photoLibraryDidChange:(PHChange *)changeInfo {
dispatch_async(dispatch_get_main_queue(), ^{
PHFetchResultChangeDetails *changes = [changeInfo changeDetailsForFetchResult:self.imageAssetsResult];
if (changes) {
self.photosDataSource.itemArray = [self getImageAssets];
[self.photosView reloadData];
}
});
}
這個方法默認所有相冊的變更都會通知,但是有些變動是我們不需要的,比如用戶新建了一個新空相冊,刪除了一個舊相冊等,這時我們可以用PHChange里的changeDetails去區(qū)分,比如changeDetailsForFetchResult:(PHFetchResult *)object;就是傳入一組FetchResult,如果這組Result有變化,比如這組Result是Asset的集合,Asset增加減少,那么就會返回一個ChangeDetails,可以用此區(qū)分,但是如果是Asset內(nèi)部的變化,就不會返回一個ChangeDetails。同樣的如果這組Result是Collection的集合,那么Collection內(nèi)部的變化,比如Collection里的Asset對象增加減少,就不會有返回。
具體可以見蘋果官方的例子
最后
這篇文章篇幅不多,作為一些補充,希望能幫到有需要的人。
如果您覺得有幫助,不妨給個star鼓勵一下,歡迎關注&交流
有任何問題歡迎評論私信或者提issue
QQ:757765420
Email:nemocdz@gmail.com
Github:Nemocdz
微博:@Nemocdz