iOS 获取系统通知开关状态[隐式推送]

之前项目中获取是否开启通知权限一直都是用的一下方法 如果拿到setting.types == UIUserNotificationTypeNone 则表示通知未开启

        UIUserNotificationSettings *setting = [[UIApplication sharedApplication] currentUserNotificationSettings];
        if (UIUserNotificationTypeNone == setting.types) {
           NSLog(@"推送权限未开启 开启弹窗提醒");
            [self showNotiView];
        }

今天同事突然问我为啥咱们的app老是弹窗提醒让他开启推送,可是推送开关已经是开启状态了呀,我仔细查看了他手机的推送设置,发现推送开关下面有一个隐式推送【OS12后新增的功能】的中文提示,我想问题应该就是出在这里 。
定位到问题后,拿到一个测试机在XCode里断点调试,发现处于隐式推送状态下,setting.types 取到的值仍然是0,所以可以得出结论在iOS12以后使用UIUserNotificationSettings是没法准确获通知开关的
通过查找资料发现 通过UNUserNotificationCenter通知中心也可以拿到通知的开启和关闭状态,UNUserNotificationCenter是iOS10以后推出来的UserNotifications.framework【需要将UserNotifications.framework添加到项目中并引入头文件】,经过验证可以准确获取到通知权限开关的开启和关闭 具体代码如下:

#import <UserNotifications/UserNotifications.h>
    if(@available(iOS 10.0, *)){
        [UNUserNotificationCenter.currentNotificationCenter getNotificationSettingsWithCompletionHandler:^(UNNotificationSettings * _Nonnull settings) {
            switch (settings.authorizationStatus) {
                case UNAuthorizationStatusAuthorized:
                    NSLog(@"推送开启状态");
                    
                    break;
                case UNAuthorizationStatusDenied:{
                    NSLog(@"推送状态关闭");
                    dispatch_async(dispatch_get_main_queue(), ^{
                        [self showNotiView];
                    });
                }
                    break;
                    
                default:
                    break;
            }
        }];
    }else{
        UIUserNotificationSettings *setting = [[UIApplication sharedApplication] currentUserNotificationSettings];
        if (UIUserNotificationTypeNone == setting.types) {
            [self showNotiView];
        }
    }

特别需要注意的是getNotificationSettingsWithCompletionHandler这个block回调在子线程,所以,如果想要刷新UI,一定要将UI刷新部分放在主线程中执行

posted @ 2021-12-30 14:04  qqcc1388  阅读(1341)  评论(0编辑  收藏  举报