之前项目中获取是否开启通知权限一直都是用的一下方法 如果拿到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刷新部分放在主线程中执行