我正在寻找一种方法来确定用户是否通过设置启用或禁用了我的应用程序的推送通知。
我正在寻找一种方法来确定用户是否通过设置启用或禁用了我的应用程序的推送通知。
调用enabledRemoteNotificationsTypes
并检查掩码。
例如:
UIRemoteNotificationType types = [[UIApplication sharedApplication] enabledRemoteNotificationTypes];
if (types == UIRemoteNotificationTypeNone)
// blah blah blah
iOS8及以上版本:
[[UIApplication sharedApplication] isRegisteredForRemoteNotifications]
quantumpotato的问题:
其中types
由以下给出
UIRemoteNotificationType types = [[UIApplication sharedApplication] enabledRemoteNotificationTypes];
可以使用
if (types & UIRemoteNotificationTypeAlert)
代替if (types == UIRemoteNotificationTypeNone)
这将允许你仅检查通知是否已启用(不用担心声音,徽章,通知中心等)。 第一行代码(types & UIRemoteNotificationTypeAlert
)将返回 YES
,如果“警报样式”设置为“横幅”或“警报”,并且如果“警报样式”设置为“无”,则返回 NO
,而不考虑其他设置。
grantedSettings.types.contains(notificationType)
。 - Philipp Otto更新的Swift 4.0代码,适用于iOS 11
import UserNotifications
UNUserNotificationCenter.current().getNotificationSettings { (settings) in
print("Notification settings: \(settings)")
guard settings.authorizationStatus == .authorized else { return }
//Not authorised
UIApplication.shared.registerForRemoteNotifications()
}
Swift 3.0的代码,适用于iOS 10。
let isRegisteredForRemoteNotifications = UIApplication.shared.isRegisteredForRemoteNotifications
if isRegisteredForRemoteNotifications {
// User is registered for notification
} else {
// Show alert user is not registered for notification
}
从 iOS9 开始,swift 2.0 中的 UIRemoteNotificationType 已经被弃用,请使用以下代码。let notificationType = UIApplication.shared.currentUserNotificationSettings!.types
if notificationType == UIUserNotificationType.none {
// Push notifications are disabled in setting by user.
}else{
// Push notifications are enabled in setting by user.
}
只需检查推送通知是否已启用
if notificationType == UIUserNotificationType.badge {
// the application may badge its icon upon a notification being received
}
if notificationType == UIUserNotificationType.sound {
// the application may play a sound upon a notification being received
}
if notificationType == UIUserNotificationType.alert {
// the application may display an alert upon a notification being received
}
在最新版本的iOS中,此方法已被弃用。为了支持iOS 7和iOS 8,请使用:
UIApplication *application = [UIApplication sharedApplication];
BOOL enabled;
// Try to use the newer isRegisteredForRemoteNotifications otherwise use the enabledRemoteNotificationTypes.
if ([application respondsToSelector:@selector(isRegisteredForRemoteNotifications)])
{
enabled = [application isRegisteredForRemoteNotifications];
}
else
{
UIRemoteNotificationType types = [application enabledRemoteNotificationTypes];
enabled = types & UIRemoteNotificationTypeAlert;
}
UserNotifications
。很抱歉,我现在没有完整的答案。 - Mazyod以下是一个完整的示例,涵盖了iOS8和iOS7(以及更低版本)。请注意,在iOS8之前,您无法区分“禁用远程通知”和“仅在锁定屏幕中查看”。
BOOL remoteNotificationsEnabled = false, noneEnabled,alertsEnabled, badgesEnabled, soundsEnabled;
if ([[UIApplication sharedApplication] respondsToSelector:@selector(registerUserNotificationSettings:)]) {
// iOS8+
remoteNotificationsEnabled = [UIApplication sharedApplication].isRegisteredForRemoteNotifications;
UIUserNotificationSettings *userNotificationSettings = [UIApplication sharedApplication].currentUserNotificationSettings;
noneEnabled = userNotificationSettings.types == UIUserNotificationTypeNone;
alertsEnabled = userNotificationSettings.types & UIUserNotificationTypeAlert;
badgesEnabled = userNotificationSettings.types & UIUserNotificationTypeBadge;
soundsEnabled = userNotificationSettings.types & UIUserNotificationTypeSound;
} else {
// iOS7 and below
UIRemoteNotificationType enabledRemoteNotificationTypes = [UIApplication sharedApplication].enabledRemoteNotificationTypes;
noneEnabled = enabledRemoteNotificationTypes == UIRemoteNotificationTypeNone;
alertsEnabled = enabledRemoteNotificationTypes & UIRemoteNotificationTypeAlert;
badgesEnabled = enabledRemoteNotificationTypes & UIRemoteNotificationTypeBadge;
soundsEnabled = enabledRemoteNotificationTypes & UIRemoteNotificationTypeSound;
}
if ([[UIApplication sharedApplication] respondsToSelector:@selector(registerUserNotificationSettings:)]) {
NSLog(@"Remote notifications enabled: %@", remoteNotificationsEnabled ? @"YES" : @"NO");
}
NSLog(@"Notification type status:");
NSLog(@" None: %@", noneEnabled ? @"enabled" : @"disabled");
NSLog(@" Alerts: %@", alertsEnabled ? @"enabled" : @"disabled");
NSLog(@" Badges: %@", badgesEnabled ? @"enabled" : @"disabled");
NSLog(@" Sounds: %@", soundsEnabled ? @"enabled" : @"disabled");
Swift 3+
if #available(iOS 10.0, *) {
UNUserNotificationCenter.current().getNotificationSettings(completionHandler: { (settings: UNNotificationSettings) in
// settings.authorizationStatus == .authorized
})
} else {
return UIApplication.shared.currentUserNotificationSettings?.types.contains(UIUserNotificationType.alert) ?? false
}
iOS10+的RxSwift可观察版本:
import UserNotifications
extension UNUserNotificationCenter {
static var isAuthorized: Observable<Bool> {
return Observable.create { observer in
DispatchQueue.main.async {
current().getNotificationSettings(completionHandler: { (settings: UNNotificationSettings) in
if settings.authorizationStatus == .authorized {
observer.onNext(true)
observer.onCompleted()
} else {
current().requestAuthorization(options: [.badge, .alert, .sound]) { (granted, error) in
observer.onNext(granted)
observer.onCompleted()
}
}
})
}
return Disposables.create()
}
}
}
getNotificationSettings(...)
是异步的,因此其中的返回值将被忽略。 - shelll尝试同时支持iOS8及以下版本时,我按照Kevin的建议并没有成功使用isRegisteredForRemoteNotifications
。相反,我使用了currentUserNotificationSettings
,在我的测试中效果非常好。
+ (BOOL)notificationServicesEnabled {
BOOL isEnabled = NO;
if ([[UIApplication sharedApplication] respondsToSelector:@selector(currentUserNotificationSettings)]){
UIUserNotificationSettings *notificationSettings = [[UIApplication sharedApplication] currentUserNotificationSettings];
if (!notificationSettings || (notificationSettings.types == UIUserNotificationTypeNone)) {
isEnabled = NO;
} else {
isEnabled = YES;
}
} else {
UIRemoteNotificationType types = [[UIApplication sharedApplication] enabledRemoteNotificationTypes];
if (types & UIRemoteNotificationTypeAlert) {
isEnabled = YES;
} else{
isEnabled = NO;
}
}
return isEnabled;
}
很不幸,所有这些解决方案都不能真正解决问题,因为归根结底,API在提供相关信息方面严重不足。你可以进行一些猜测,但是使用currentUserNotificationSettings
(iOS8+)在当前形式下并不足以真正回答这个问题。尽管这里的许多解决方案似乎表明这种方法或者isRegisteredForRemoteNotifications
更具有决定性,但实际上并非如此。
考虑以下情况:
对于isRegisteredForRemoteNotifications
,文档中指出:
如果应用程序当前已注册接收远程通知,则返回YES,考虑任何系统范围内的设置...
然而,如果你在应用代理中插入一个简单的NSLog
来观察其行为,我们可以清楚地看到它并未按照我们所预期的方式工作。它实际上与已激活此应用/设备的远程通知直接相关。第一次激活后,它将始终返回YES
。即使在“设置”(通知)中关闭它们,仍会导致它返回YES
。这是因为从iOS8开始,应用程序可以注册远程通知并向设备发送它们,而不需要用户启用通知,他们只是不能进行警报、徽章和声音等操作,除非用户打开这些选项。无声通知是一个你可能会继续使用的好例子,即使通知被关闭。
至于currentUserNotificationSettings
,它指示以下四种情况之一:
警报已开启 徽章已开启 声音已开启 没有开启。
这根本不能给你任何关于其他因素或通知开关本身的指示。
用户实际上可能关闭徽章、声音和警报,但仍然在锁屏或通知中心中显示。这个用户应该仍然能够接收推送通知,并且能够在锁屏和通知中心中看到它们。他们已经打开了通知开关。但在这种情况下,currentUserNotificationSettings
将返回:UIUserNotificationTypeNone
。这不真正反映了用户的实际设置。
以下是一些猜测:
isRegisteredForRemoteNotifications
为NO
,则可以假设此设备从未成功注册过远程通知。application:didRegisterUserNotificationSettings:
,其中包含此时的用户通知设置,因为这是第一次注册用户,设置应该表明用户选择了什么样的权限请求。如果设置与UIUserNotificationTypeNone
不同,则表示已授予推送权限,否则已拒绝。原因是从您开始远程注册流程的那一刻起,用户只能接受或拒绝,最初的设置是您在注册过程中设置的接受设置。UIRemoteNotificationType types = [[UIApplication sharedApplication] enabledRemoteNotificationTypes];
switch (types) {
case UIRemoteNotificationTypeAlert:
case UIRemoteNotificationTypeBadge:
// For enabled code
break;
case UIRemoteNotificationTypeSound:
case UIRemoteNotificationTypeNone:
default:
// For disabled code
break;
}
UIRemoteNotificationType types = [[UIApplication sharedApplication] enabledRemoteNotificationTypes];
UIRemoteNotificationType typesset = (UIRemoteNotificationTypeAlert | UIRemoteNotificationTypeBadge);
if((types & typesset) == typesset)
{
CeldaSwitch.chkSwitch.on = true;
}
else
{
CeldaSwitch.chkSwitch.on = false;
}
#import <UserNotifications/UserNotifications.h>
[[UNUserNotificationCenter currentNotificationCenter]getNotificationSettingsWithCompletionHandler:^(UNNotificationSettings * _Nonnull settings) {
switch (settings.authorizationStatus) {
case UNAuthorizationStatusNotDetermined:{
break;
}
case UNAuthorizationStatusDenied:{
break;
}
case UNAuthorizationStatusAuthorized:{
break;
}
default:
break;
}
}];
[[UIApplication sharedApplication] currentUserNotificationSettings];
。 - Apan