之前項目中獲取是否開啟通知權限一直都是用的一下方法 如果拿到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刷新部分放在主線程中執行
