获取相册权限,网上的写法,大多都感觉有点问题,不是特别完美.
方案1: 直接给了返回值, 那对于PHAuthorizationStatusNotDetermined这种的,后面可能权限给了不允许, 然后还去调保存相册就会出问题. 这种方案不通过.
+ (BOOL)hasPermissionForPhotoGallery {
PHAuthorizationStatus status = [PHPhotoLibrary authorizationStatus];
if (status == PHAuthorizationStatusRestricted || status == PHAuthorizationStatusDenied) {
return NO;
}
return YES;
}
方案2: 加了信号量,用信号量阻塞线程,当用户做了决定之后再返回. 看上去是没有问题的, 但是在使用的过程中发现了线程卡死.
第一次的时候 , 系统请求权限的弹框迟迟不出来,点击屏幕没有响应,之后推出一次后台,权限的弹窗才出现,同意/不同意 权限之后,才能解除死锁,不通过
+ (BOOL)isCanVisitPhotoLibrary {
PHAuthorizationStatus status = [PHPhotoLibrary authorizationStatus];
if (status == PHAuthorizationStatusAuthorized) {
return YES;
}
if (status == PHAuthorizationStatusRestricted || status == PHAuthorizationStatusDenied) {
return NO;
}
__block BOOL isAblity = YES;
dispatch_semaphore_t semaphore = dispatch_semaphore_create(0);
dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
dispatch_async(queue, ^{
[PHPhotoLibrary requestAuthorization:^(PHAuthorizationStatus status) {
if (status != PHAuthorizationStatusAuthorized) {
NSLog(@"未开启相册权限,请到设置中开启");
isAblity = NO;
dispatch_semaphore_signal(semaphore);
}
}];
});
dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER);
return isAblity;
}
最终结果,由于PHAuthorizationStatusNotDetermined 这种的肯定是异步的给出结果,所以只能以异步对抗异步(用魔法打败魔法) , 所以结果只能在block中给出, 就变成了下面的这样,不会造成死锁,block中的结果肯定正确.
其他的相机,麦克风权限的获取也可以按照类似的方式
//MARK:相册权限检测
+ (void)isCanVisitPhotoLibrary:(void(^)(BOOL))result {
/// 获取当前的状态
//+ (PHAuthorizationStatus)authorizationStatus;
/// 请求权限
//+ (void)requestAuthorization:(void(^)(PHAuthorizationStatus status))handler;
PHAuthorizationStatus status = [PHPhotoLibrary authorizationStatus];
if (status == PHAuthorizationStatusAuthorized) {
result(YES);
return;
}
if (status == PHAuthorizationStatusRestricted || status == PHAuthorizationStatusDenied) {
result(NO);
return ;
}
if (status == PHAuthorizationStatusNotDetermined) {
[PHPhotoLibrary requestAuthorization:^(PHAuthorizationStatus status) {
// 回调是在子线程的
NSLog(@"%@",[NSThread currentThread]);
dispatch_async(dispatch_get_main_queue(), ^{
if (status != PHAuthorizationStatusAuthorized) {
NSLog(@"未开启相册权限,请到设置中开启");
result(NO);
return ;
}
result(YES);
});
}];
}
}