ios 在 iPhone 上确定用户是否启用了推送通知

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/1535403/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-30 16:30:35  来源:igfitidea点击:

Determine on iPhone if user has enabled push notifications

iosiphonenotificationsapple-push-notificationspush

提问by Kevin

I'm looking for a way to determine if the user has, via settings, enabled or disabled their push notifications for my application.

我正在寻找一种方法来确定用户是否通过设置为我的应用程序启用或禁用了他们的推送通知。

回答by Zac Bowling

Call enabledRemoteNotificationsTypesand check the mask.

打电话enabledRemoteNotificationsTypes检查面罩。

For example:

例如:

UIRemoteNotificationType types = [[UIApplication sharedApplication] enabledRemoteNotificationTypes];
if (types == UIRemoteNotificationTypeNone) 
   // blah blah blah

iOS8 and above:

iOS8及以上:

[[UIApplication sharedApplication] isRegisteredForRemoteNotifications]

回答by Tim Camber

quantumpotato's issue:

量子土豆的问题:

Where typesis given by

哪里types给出

UIRemoteNotificationType types = [[UIApplication sharedApplication] enabledRemoteNotificationTypes];

one can use

一个可以使用

if (types & UIRemoteNotificationTypeAlert)

instead of

代替

if (types == UIRemoteNotificationTypeNone) 

will allow you to check only whether notifications are enabled (and don't worry about sounds, badges, notification center, etc.). The first line of code (types & UIRemoteNotificationTypeAlert) will return YESif "Alert Style" is set to "Banners" or "Alerts", and NOif "Alert Style" is set to "None", irrespective of other settings.

将允许您仅检查通知是否已启用(而不必担心声音、徽章、通知中心等)。如果“警报样式”设置为“横幅”或“警报”,并且“警报样式”设置为“无”,则第一行代码 ( types & UIRemoteNotificationTypeAlert) 将返回,无论其他设置如何。YESNO

回答by Kevin Sylvestre

In the latest version of iOS this method is now deprecated. To support both iOS 7 and iOS 8 use:

在最新版本的 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;
}

回答by ViJay Avhad

Updated code for swift4.0 , iOS11

swift4.0 和 iOS11 的更新代码

import UserNotifications

UNUserNotificationCenter.current().getNotificationSettings { (settings) in
   print("Notification settings: \(settings)")
   guard settings.authorizationStatus == .authorized else { return }

   //Not authorised 
   UIApplication.shared.registerForRemoteNotifications()
}

Code for swift3.0 , iOS10

swift3.0 , iOS10 的代码

    let isRegisteredForRemoteNotifications = UIApplication.shared.isRegisteredForRemoteNotifications
    if isRegisteredForRemoteNotifications {
        // User is registered for notification
    } else {
        // Show alert user is not registered for notification
    }

From iOS9 , swift 2.0 UIRemoteNotificationType is deprecated, use following code

从 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.

}

simply check whether Push notifications are enabled

只需检查是否启用推送通知

    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
    }

回答by tilo

Below you'll find a complete example that covers both iOS8 and iOS7 (and lower versions). Please note that prior to iOS8 you can't distinguish between "remote notifications disabled" and "only View in lockscreenenabled".

您将在下面找到一个涵盖 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");

回答by Adam Smaka

Swift 3+

斯威夫特 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
    }

RxSwift Observable Version for iOS10+:

适用于 iOS10+ 的 RxSwift Observable 版本:

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()
        }
    }
}

回答by Shaheen Ghiassy

In trying to support both iOS8 and lower, I didn't have much luck using isRegisteredForRemoteNotificationsas Kevin suggested. Instead I used currentUserNotificationSettings, which worked great in my testing.

在尝试同时支持 iOS8 和更低版本时,我没有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;
}

回答by iYorke

Unfortunately none of these solutions provided reallysolve the problem because at the end of the day the APIs are seriously lacking when it comes to providing the pertinent information. You can make a few guesses however using currentUserNotificationSettings(iOS8+) just isn't sufficient in its current form to really answer the question. Although a lot of the solutions here seem to suggest that either that or isRegisteredForRemoteNotificationsis more of a definitive answer it really is not.

不幸的是,这些提供的解决方案都没有真正解决问题,因为归根结底,API 在提供相关信息方面严重缺乏。您可以进行一些猜测,但是使用currentUserNotificationSettings(iOS8+) 仅以其当前形式不足以真正回答问题。尽管这里的许多解决方案似乎都表明这是isRegisteredForRemoteNotifications一个明确的答案,但实际上并非如此。

Consider this:

考虑一下:

with isRegisteredForRemoteNotificationsdocumentation states:

isRegisteredForRemoteNotifications文档状态:

Returns YES if the application is currently registered for remote notifications, taking into account any systemwide settings...

如果应用程序当前已注册远程通知,则返回 YES,同时考虑任何系统范围的设置...

However if you throw a simply NSLoginto your app delegate to observe the behavior it is clear this does not behave the way we are anticipating it will work. It actually pertains directly to remote notifications having been activated for this app/device. Once activated for the first time this will always return YES. Even turning them off in settings (notifications) will still result in this returning YESthis is because, as of iOS8, an app may register for remote notifications and even send to a device without the user having notifications enabled, they just may not do Alerts, Badges and Sound without the user turning that on. Silent notifications are a good example of something you may continue to do even with notifications turned off.

但是,如果您简单地将 aNSLog放入您的应用程序委托以观察行为,很明显这不会像我们预期的那样工作。它实际上直接与为此应用程序/设备激活的远程通知有关。一旦第一次激活,这将始终返回YES。即使在设置(通知)中关闭它们仍然会导致返回YES这是因为,从 iOS8 开始,应用程序可能会注册远程通知,甚至在用户未启用通知的情况下发送到设备,他们可能不会发出警报,徽章和声音无需用户打开。静默通知就是一个很好的例子,说明即使关闭通知,您也可以继续做一些事情。

As far as currentUserNotificationSettingsit indicates one of four things:

至于currentUserNotificationSettings它表明四件事之一:

Alerts are on Badges are on Sound is on None are on.

警报开启 徽章开启 声音开启 无开启。

This gives you absolutely no indication whatsoever about the other factors or the Notification switch itself.

这绝对不会为您提供有关其他因素或通知开关本身的任何指示。

A user may in fact turn off badges, sound and alerts but still have show on lockscreen or in notification center. This user should still be receiving push notifications and be able to see them both on the lock screen and in the notification center. They have the notification switch on. BUT currentUserNotificationSettingswill return: UIUserNotificationTypeNonein that case. This is not truly indicative of the users actual settings.

用户实际上可能会关闭徽章、声音和警报,但仍会在锁屏或通知中心显示。该用户应该仍能接收推送通知,并且能够在锁定屏幕和通知中心看到它们。他们打开了通知。但是currentUserNotificationSettings会返回:UIUserNotificationTypeNone在这种情况下。这并不真正代表用户的实际设置。

A few guesses one can make:

人们可以做出一些猜测:

  • if isRegisteredForRemoteNotificationsis NOthen you can assume that this device has never successfully registered for remote notifications.
  • after the first time of registering for remote notifications a callback to application:didRegisterUserNotificationSettings:is made containing user notification settings at this time since this is the first time a user has been registered the settings shouldindicate what the user selected in terms of the permission request. If the settings equate to anything other than: UIUserNotificationTypeNonethen push permission was granted, otherwise it was declined. The reason for this is that from the moment you begin the remote registration process the user only has the ability to accept or decline, with the initial settings of an acceptance being the settings you setup during the registration process.
  • 如果isRegisteredForRemoteNotifications是,NO那么您可以假设该设备从未成功注册远程通知。
  • 在第一次注册远程通知后,此时application:didRegisterUserNotificationSettings:会进行包含用户通知设置的回调,因为这是用户第一次注册,设置指示用户根据权限请求选择了什么。如果设置等于以下任何内容:UIUserNotificationTypeNone则授予推送权限,否则拒绝。这样做的原因是,从您开始远程注册过程的那一刻起,用户只能接受或拒绝,接受的初始设置是您在注册过程中设置的设置。

回答by pojomx

To complete the answer, it could work something like this...

要完成答案,它可以像这样工作......

UIRemoteNotificationType types = [[UIApplication sharedApplication] enabledRemoteNotificationTypes];
switch (types) {
   case UIRemoteNotificationTypeAlert:
   case UIRemoteNotificationTypeBadge:
       // For enabled code
       break;
   case UIRemoteNotificationTypeSound:
   case UIRemoteNotificationTypeNone:
   default:
       // For disabled code
       break;
}

edit: This is not right. since these are bit-wise stuff, it wont work with a switch, so I ended using this:

编辑:这是不对的。因为这些是按位的东西,它不能与开关一起使用,所以我结束了使用这个:

UIRemoteNotificationType types = [[UIApplication sharedApplication] enabledRemoteNotificationTypes];
UIRemoteNotificationType typesset = (UIRemoteNotificationTypeAlert | UIRemoteNotificationTypeBadge);
if((types & typesset) == typesset)
{
    CeldaSwitch.chkSwitch.on = true;
}
else
{
    CeldaSwitch.chkSwitch.on = false;
}

回答by Peter Verhage

For iOS7 and before you should indeed use enabledRemoteNotificationTypesand check if it equals (or doesn't equal depending on what you want) to UIRemoteNotificationTypeNone.

对于 iOS7 和之前,您确实应该使用enabledRemoteNotificationTypes并检查它是否等于(或不等于,取决于您想要的)到UIRemoteNotificationTypeNone.

However for iOS8 it is notalways enough to only check with isRegisteredForRemoteNotificationsas many state above. You should also check if application.currentUserNotificationSettings.typesequals (or doesn't equal depending on what you want) UIUserNotificationTypeNone!

然而,对于 iOS8 ,仅检查上述多个状态并不总是足够的isRegisteredForRemoteNotifications。您还应该检查是否application.currentUserNotificationSettings.types等于(或不等于,取决于您想要什么)UIUserNotificationTypeNone

isRegisteredForRemoteNotificationsmight return true even though currentUserNotificationSettings.typesreturns UIUserNotificationTypeNone.

isRegisteredForRemoteNotifications即使currentUserNotificationSettings.types返回UIUserNotificationTypeNone.