You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.20 10:52:40