之前寫了一個(gè)仿Snapseed的ImagePicker酵紫,見Demo和之前的簡(jiǎn)書文章唉俗,
之后發(fā)現(xiàn)有人說第一次未授權(quán)時(shí)collectionview會(huì)加載不出照片,發(fā)現(xiàn)沒有在合適時(shí)候調(diào)用權(quán)限管理。iOS10的這個(gè)權(quán)限管理是info.plist的一個(gè)鍵值源祈,沒有回調(diào)方法。查詢photoskit方法里色迂,發(fā)現(xiàn)有一個(gè)權(quán)限回調(diào)方法香缺,就想封裝一個(gè)方法來友好的詢問用戶權(quán)限。
查詢文檔歇僧,相冊(cè)權(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. 一般是家長(zhǎng)權(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);
其中,我們不希望用戶去拒絕诈悍,達(dá)到PHAuthorizationStatusDenied
這個(gè)狀態(tài)祸轮,這樣的話用戶再要獲取權(quán)限就要到設(shè)置里的隱私里找到我們的應(yīng)用再手動(dòng)打開,而沒辦法在app內(nèi)去請(qǐng)求權(quán)限更改侥钳。那么我們希望暫時(shí)拒絕后的狀態(tài)應(yīng)該是PHAuthorizationStatusNotDetermined
的适袜,思路就是提示一個(gè)alertviewcontroller去詢問,用戶取消則不去調(diào)用真正的詢問權(quán)限(相當(dāng)于忽略)舷夺,以便下次提醒在詢問珍策。用戶同意則調(diào)用系統(tǒng)詢問權(quán)限,這時(shí)一般用戶也會(huì)再允許了芽死。流程示意圖如下牢屋。
代碼很簡(jiǎn)單,直接貼上來
- (void)showPermissionAlertInController{
UIAlertController *alert = [UIAlertController alertControllerWithTitle:nil message:@"需要你的圖庫(kù)的權(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)相冊(cè)");
}else {
NSLog(@"用戶拒絕授權(quán)相冊(cè)");
}
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)用選擇器時(shí)在外部改變了照片(增加耙册,刪除)后collectionview不會(huì)改變给僵,就研究了一下photoskit,發(fā)現(xiàn)有個(gè)- (void)photoLibraryDidChange:(PHChange *)changeInfo
檢測(cè)相冊(cè)變動(dòng),但之前需要注冊(cè)為觀察者并實(shí)現(xiàn)協(xié)議
PHPhotoLibraryChangeObserver
- (void)viewDidLoad{
[super viewDidLoad];
[[PHPhotoLibrary sharedPhotoLibrary]registerChangeObserver:self];
//other code
}
- (void)dealloc{
[[PHPhotoLibrary sharedPhotoLibrary]unregisterChangeObserver:self];
}
然后實(shí)現(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];
}
});
}
這個(gè)方法默認(rèn)所有相冊(cè)的變更都會(huì)通知蔓同,但是有些變動(dòng)是我們不需要的,比如用戶新建了一個(gè)新空相冊(cè)蹲诀,刪除了一個(gè)舊相冊(cè)等斑粱,這時(shí)我們可以用PHChange里的changeDetails去區(qū)分,比如changeDetailsForFetchResult:(PHFetchResult *)object;
就是傳入一組FetchResult脯爪,如果這組Result有變化则北,比如這組Result是Asset的集合,Asset增加減少痕慢,那么就會(huì)返回一個(gè)ChangeDetails尚揣,可以用此區(qū)分,但是如果是Asset內(nèi)部的變化掖举,就不會(huì)返回一個(gè)ChangeDetails快骗。同樣的如果這組Result是Collection的集合,那么Collection內(nèi)部的變化塔次,比如Collection里的Asset對(duì)象增加減少方篮,就不會(huì)有返回。
具體可以見蘋果官方的例子
最后
這篇文章篇幅不多励负,作為一些補(bǔ)充藕溅,希望能幫到有需要的人。
如果您覺得有幫助,不妨給個(gè)star鼓勵(lì)一下,歡迎關(guān)注&交流
有任何問題歡迎評(píng)論私信或者提issue
QQ:757765420
Email:nemocdz@gmail.com
Github:Nemocdz
微博:@Nemocdz