如何在Objective-C中正确获取通知权限?解决异步返回值错误
修复iOS推送权限获取方法的问题
原方法的核心问题是getNotificationSettingsWithCompletionHandler:是异步方法,它的回调block会在方法执行完成后才触发(日志里先打印555再打印111就是明证)。当你在方法末尾返回hasPermission时,block还没执行,此时hasPermission是默认的NO,所以外部调用拿到的永远是错误值。
由于iOS系统禁止主线程同步等待异步操作(会导致界面卡顿甚至被系统终止),正确的做法是改用回调block返回权限结果,重写后的代码如下:
- (void)getNotificationPermissionWithCompletion:(void(^)(BOOL hasPermission))completion { UNUserNotificationCenter *center = [UNUserNotificationCenter currentNotificationCenter]; [center getNotificationSettingsWithCompletionHandler:^(UNNotificationSettings *settings){ BOOL permissionStatus = NO; switch (settings.authorizationStatus) { case UNAuthorizationStatusAuthorized: permissionStatus = YES; NSLog(@"111"); break; case UNAuthorizationStatusDenied: permissionStatus = NO; NSLog(@"222"); break; case UNAuthorizationStatusNotDetermined: permissionStatus = NO; NSLog(@"333"); break; default: permissionStatus = NO; NSLog(@"444"); break; } // 确保回调在主线程执行(若需更新UI必须切换到主线程) dispatch_async(dispatch_get_main_queue(), ^{ if (completion) { completion(permissionStatus); } }); }]; }
外部调用方式
[self getNotificationPermissionWithCompletion:^(BOOL hasPermission) { // 在这里处理权限结果 if (hasPermission) { // 推送已授权,执行对应逻辑 } else { // 未授权或权限未确定,执行对应逻辑 } }];
补充说明
- 异步回调是iOS处理异步操作的标准方案,避免了主线程阻塞问题
- 若业务逻辑必须依赖权限结果才能继续,需把后续逻辑放在completion block内执行
- 回调中加入主线程切换,是因为系统的completion handler可能在后台线程触发,更新UI操作必须在主线程执行
内容的提问来源于stack exchange,提问作者Beginnerrrrrr
相关产品推荐
相关产品推荐

