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

发布于 2024-08-06 12:48:35 字数 45 浏览 7 评论 0原文

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

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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(19

唠甜嗑 2024-08-13 12:48:35

调用enabledRemoteNotificationsTypes并检查掩码。

例如:

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

iOS8及以上版本:

[[UIApplication sharedApplication] isRegisteredForRemoteNotifications]

Call enabledRemoteNotificationsTypes and check the mask.

For example:

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

iOS8 and above:

[[UIApplication sharedApplication] isRegisteredForRemoteNotifications]
想挽留 2024-08-13 12:48:35

Quantumpotato 的问题:

其中 types 是由

UIRemoteNotificationType types = [[UIApplication sharedApplication] enabledRemoteNotificationTypes];

一个可以使用的

if (types & UIRemoteNotificationTypeAlert)

代替

if (types == UIRemoteNotificationTypeNone) 

的给出的,它允许您仅检查通知是否已启用(并且不用担心声音、徽章、通知中心等)。如果“Alert Style”设置为“Banners”或“Alerts”,第一行代码 (types & UIRemoteNotificationTypeAlert) 将返回 YES,并且 NO< /code> 如果“警报样式”设置为“无”,无论其他设置如何。

quantumpotato's issue:

Where types is given by

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 YES if "Alert Style" is set to "Banners" or "Alerts", and NO if "Alert Style" is set to "None", irrespective of other settings.

聆听风音 2024-08-13 12:48:35

更新了 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()
}

更新了 swift3.0、iOS10 的代码

    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
    }

Updated code for 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

    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

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
    }
小鸟爱天空丶 2024-08-13 12:48:35

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

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

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;
}
内心荒芜 2024-08-13 12:48:35

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

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 lockscreen enabled".

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");
只涨不跌 2024-08-13 12:48:35

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

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
    }

RxSwift Observable Version for iOS10+:

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()
        }
    }
}
莫相离 2024-08-13 12:48:35

在尝试支持 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;
}

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

+ (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;
}
三月梨花 2024-08-13 12:48:35

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

考虑一下:

isRegisteredForRemoteNotifications 文档指出:

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

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

currentUserNotificationSettings 而言,它指示以下四件事之一:

警报已开启
徽章已开启
声音已打开
没有一个打开。

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

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

人们可以做出一些猜测:

  • 如果 isRegisteredForRemoteNotificationsNO 那么您可以假设该设备从未成功注册远程通知。
  • 第一次注册远程通知后,会对 application:didRegisterUserNotificationSettings: 进行回调,此时包含用户通知设置,因为这是用户第一次注册,设置应该< /em> 指示用户在权限请求方面选择的内容。如果设置等于 UIUserNotificationTypeNone 以外的任何内容,则授予推送权限,否则将被拒绝。原因是,从您开始远程注册过程的那一刻起,用户只能接受或拒绝,接受的初始设置是您在注册过程中设置的设置。

Unfortunately none of these solutions provided really solve 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 isRegisteredForRemoteNotifications is more of a definitive answer it really is not.

Consider this:

with isRegisteredForRemoteNotifications documentation states:

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

However if you throw a simply NSLog into 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 YES this 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.

As far as currentUserNotificationSettings it indicates one of four things:

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 currentUserNotificationSettings will return: UIUserNotificationTypeNone in that case. This is not truly indicative of the users actual settings.

A few guesses one can make:

  • if isRegisteredForRemoteNotifications is NO then 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 should indicate what the user selected in terms of the permission request. If the settings equate to anything other than: UIUserNotificationTypeNone then 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.
明天过后 2024-08-13 12:48:35

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

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;
}

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;
}
掩饰不了的爱 2024-08-13 12:48:35

iOS8+(目标C)

#import <UserNotifications/UserNotifications.h>


[[UNUserNotificationCenter currentNotificationCenter]getNotificationSettingsWithCompletionHandler:^(UNNotificationSettings * _Nonnull settings) {

    switch (settings.authorizationStatus) {
          case UNAuthorizationStatusNotDetermined:{

            break;
        }
        case UNAuthorizationStatusDenied:{

            break;
        }
        case UNAuthorizationStatusAuthorized:{

            break;
        }
        default:
            break;
    }
}];

iOS8+ (OBJECTIVE C)

#import <UserNotifications/UserNotifications.h>


[[UNUserNotificationCenter currentNotificationCenter]getNotificationSettingsWithCompletionHandler:^(UNNotificationSettings * _Nonnull settings) {

    switch (settings.authorizationStatus) {
          case UNAuthorizationStatusNotDetermined:{

            break;
        }
        case UNAuthorizationStatusDenied:{

            break;
        }
        case UNAuthorizationStatusAuthorized:{

            break;
        }
        default:
            break;
    }
}];
等待圉鍢 2024-08-13 12:48:35

对于 iOS7 及之前的版本,您确实应该使用 enabledRemoteNotificationTypes 并检查它是否等于(或不等于,具体取决于您想要的)UIRemoteNotificationTypeNone

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

即使 currentUserNotificationSettings.types 返回 UIUserNotificationTypeNoneisRegisteredForRemoteNotifications 也可能返回 true。

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

However for iOS8 it is not always enough to only check with isRegisteredForRemoteNotifications as many state above. You should also check if application.currentUserNotificationSettings.types equals (or doesn't equal depending on what you want) UIUserNotificationTypeNone!

isRegisteredForRemoteNotifications might return true even though currentUserNotificationSettings.types returns UIUserNotificationTypeNone.

如果没结果 2024-08-13 12:48:35
UIRemoteNotificationType types = [[UIApplication sharedApplication] enabledRemoteNotificationTypes];
if (types & UIRemoteNotificationTypeAlert)
    // blah blah blah
{
    NSLog(@"Notification Enabled");
}
else
{
    NSLog(@"Notification not enabled");
}

这里我们从 UIApplication 获取 UIRemoteNotificationType。它代表了该应用程序在设置中的推送通知状态,您可以轻松查看其类型

UIRemoteNotificationType types = [[UIApplication sharedApplication] enabledRemoteNotificationTypes];
if (types & UIRemoteNotificationTypeAlert)
    // blah blah blah
{
    NSLog(@"Notification Enabled");
}
else
{
    NSLog(@"Notification not enabled");
}

Here we get the UIRemoteNotificationType from UIApplication. It represents the state of push notification of this app in the setting, than you can check on its type easily

苯莒 2024-08-13 12:48:35

我尝试使用 @Shaheen Ghiassy 提供的解决方案支持 iOS 10 及更高版本,但发现剥夺问题 enabledRemoteNotificationTypes。因此,我找到的解决方案是使用 isRegisteredForRemoteNotifications 而不是 iOS 8 中已弃用的 enabledRemoteNotificationTypes。下面是我的更新后的解决方案,非常适合我:

- (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 {

        if ([[UIApplication sharedApplication] isRegisteredForRemoteNotifications]) {
            isEnabled = YES;
        } else{
            isEnabled = NO;
        }
    }
    return isEnabled;
}

我们可以轻松调用此函数并访问其 Bool 值,并可以通过以下方式将其转换为字符串值:

NSString *str = [self notificationServicesEnabled] ? @"YES" : @"NO";

希望它也能帮助其他人:)
快乐编码。

I try to support iOS 10 and above using solution provide by @Shaheen Ghiassy but find deprivation issue enabledRemoteNotificationTypes. So, the solution I find by using isRegisteredForRemoteNotifications instead of enabledRemoteNotificationTypes which deprecated in iOS 8. Below is my updated solution that worked perfectly for me:

- (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 {

        if ([[UIApplication sharedApplication] isRegisteredForRemoteNotifications]) {
            isEnabled = YES;
        } else{
            isEnabled = NO;
        }
    }
    return isEnabled;
}

And we can call this function easily and be accessing its Bool value and can convert it into the string value by this:

NSString *str = [self notificationServicesEnabled] ? @"YES" : @"NO";

Hope it will help others too :)
Happy coding.

你丑哭了我 2024-08-13 12:48:35

尽管 Zac 的答案在 iOS 7 之前是完全正确的,但自从 iOS 8 出现以来,情况发生了变化。因为从 iOS 8 开始,enabledRemoteNotificationTypes 已被弃用。对于 iOS 8 及更高版本,您需要使用 isRegisteredForRemoteNotifications

  • 适用于 iOS 7 及之前版本 --> 使用enabledRemoteNotificationTypes
  • 对于 iOS 8 及更高版本, -->使用 isRegisteredForRemoteNotifications。

Though Zac's answer was perfectly correct till iOS 7, it has changed since iOS 8 arrived. Because enabledRemoteNotificationTypes has been deprecated from iOS 8 onwards. For iOS 8 and later, you need to use isRegisteredForRemoteNotifications.

  • for iOS 7 and before --> Use enabledRemoteNotificationTypes
  • for iOS 8 and later --> Use isRegisteredForRemoteNotifications.
楠木可依 2024-08-13 12:48:35

这个Swifty解决方案对我来说效果很好(iOS8+),

方法

func isNotificationEnabled(completion:@escaping (_ enabled:Bool)->()){
    if #available(iOS 10.0, *) {
        UNUserNotificationCenter.current().getNotificationSettings(completionHandler: { (settings: UNNotificationSettings) in
            let status =  (settings.authorizationStatus == .authorized)
            completion(status)
        })
    } else {
        if let status = UIApplication.shared.currentUserNotificationSettings?.types{
            let status = status.rawValue != UIUserNotificationType(rawValue: 0).rawValue
            completion(status)
        }else{
            completion(false)
        }
    }
}

用法

isNotificationEnabled { (isEnabled) in
            if isEnabled{
                print("Push notification enabled")
            }else{
                print("Push notification not enabled")
            }
        }

参考

This Swifty solution worked well for me (iOS8+),

Method:

func isNotificationEnabled(completion:@escaping (_ enabled:Bool)->()){
    if #available(iOS 10.0, *) {
        UNUserNotificationCenter.current().getNotificationSettings(completionHandler: { (settings: UNNotificationSettings) in
            let status =  (settings.authorizationStatus == .authorized)
            completion(status)
        })
    } else {
        if let status = UIApplication.shared.currentUserNotificationSettings?.types{
            let status = status.rawValue != UIUserNotificationType(rawValue: 0).rawValue
            completion(status)
        }else{
            completion(false)
        }
    }
}

Usage:

isNotificationEnabled { (isEnabled) in
            if isEnabled{
                print("Push notification enabled")
            }else{
                print("Push notification not enabled")
            }
        }

Ref

两仪 2024-08-13 12:48:35

回复:

这是正确的

if (types & UIRemoteNotificationTypeAlert)

,但以下也是正确的! (因为 UIRemoteNotificationTypeNone 是 0 )

if (types == UIRemoteNotificationTypeNone) 

请参阅以下内容

NSLog(@"log:%d",0 & 0); ///false
NSLog(@"log:%d",1 & 1); ///true
NSLog(@"log:%d",1<<1 & 1<<1); ///true
NSLog(@"log:%d",1<<2 & 1<<2); ///true
NSLog(@"log:%d",(0 & 0) && YES); ///false
NSLog(@"log:%d",(1 & 1) && YES); ///true
NSLog(@"log:%d",(1<<1 & 1<<1) && YES); ///true
NSLog(@"log:%d",(1<<2 & 1<<2) && YES); ///true

re:

this is correct

if (types & UIRemoteNotificationTypeAlert)

but following is correct too ! (as UIRemoteNotificationTypeNone is 0 )

if (types == UIRemoteNotificationTypeNone) 

see the following

NSLog(@"log:%d",0 & 0); ///false
NSLog(@"log:%d",1 & 1); ///true
NSLog(@"log:%d",1<<1 & 1<<1); ///true
NSLog(@"log:%d",1<<2 & 1<<2); ///true
NSLog(@"log:%d",(0 & 0) && YES); ///false
NSLog(@"log:%d",(1 & 1) && YES); ///true
NSLog(@"log:%d",(1<<1 & 1<<1) && YES); ///true
NSLog(@"log:%d",(1<<2 & 1<<2) && YES); ///true
眉目亦如画i 2024-08-13 12:48:35

以下是如何在 Xamarin.ios 中执行此操作。

public class NotificationUtils
{
    public static bool AreNotificationsEnabled ()
    {
        var settings = UIApplication.SharedApplication.CurrentUserNotificationSettings;
        var types = settings.Types;
        return types != UIUserNotificationType.None;
    }
}

如果您支持 iOS 10+,则仅使用 UNUserNotificationCenter 方法。

Here's how to do this in Xamarin.ios.

public class NotificationUtils
{
    public static bool AreNotificationsEnabled ()
    {
        var settings = UIApplication.SharedApplication.CurrentUserNotificationSettings;
        var types = settings.Types;
        return types != UIUserNotificationType.None;
    }
}

If you are supporting iOS 10+ only go with the UNUserNotificationCenter method.

谁与争疯 2024-08-13 12:48:35

在 Xamarin 中,上述所有解决方案都不适合我。
这就是我使用的:

public static bool IsRemoteNotificationsEnabled() {
    return UIApplication.SharedApplication.CurrentUserNotificationSettings.Types != UIUserNotificationType.None;
}

在您更改“设置”中的通知状态后,它也会获得实时更新。

In Xamarin, all above solution does not work for me.
This is what I use instead:

public static bool IsRemoteNotificationsEnabled() {
    return UIApplication.SharedApplication.CurrentUserNotificationSettings.Types != UIUserNotificationType.None;
}

It's getting a live update also after you've changed the notification status in Settings.

寂寞清仓 2024-08-13 12:48:35

从 @ZacBowling 的解决方案构建的完整轻松复制和粘贴代码 (https://stackoverflow.com/a/1535427/2298002)

这也将使用户进入您的应用程序设置并允许他们立即启用

我还添加了一个解决方案来检查位置服务是否已启用(并且也进入设置)

// check if notification service is enabled
+ (void)checkNotificationServicesEnabled
{
    if (![[UIApplication sharedApplication] isRegisteredForRemoteNotifications])
    {
        UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:@"Notification Services Disabled!"
                                                            message:@"Yo don't mess around bro! Enabling your Notifications allows you to receive important updates"
                                                           delegate:self
                                                  cancelButtonTitle:@"Cancel"
                                                  otherButtonTitles:@"Settings", nil];

        alertView.tag = 300;

        [alertView show];

        return;
    }
}

// check if location service is enabled (ref: https://stackoverflow.com/a/35982887/2298002)
+ (void)checkLocationServicesEnabled
{
    //Checking authorization status
    if (![CLLocationManager locationServicesEnabled] || [CLLocationManager authorizationStatus] == kCLAuthorizationStatusDenied)
    {

        UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:@"Location Services Disabled!"
                                                            message:@"You need to enable your GPS location right now!!"
                                                           delegate:self
                                                  cancelButtonTitle:@"Cancel"
                                                  otherButtonTitles:@"Settings", nil];

        //TODO if user has not given permission to device
        if (![CLLocationManager locationServicesEnabled])
        {
            alertView.tag = 100;
        }
        //TODO if user has not given permission to particular app
        else
        {
            alertView.tag = 200;
        }

        [alertView show];

        return;
    }
}

// handle bringing user to settings for each
+ (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex
{

    if(buttonIndex == 0)// Cancel button pressed
    {
        //TODO for cancel
    }
    else if(buttonIndex == 1)// Settings button pressed.
    {
        if (alertView.tag == 100)
        {
            //This will open ios devices location settings
            [[UIApplication sharedApplication] openURL:[NSURL URLWithString:@"prefs:root=LOCATION_SERVICES"]];
        }
        else if (alertView.tag == 200)
        {
            //This will open particular app location settings
            [[UIApplication sharedApplication] openURL:[NSURL URLWithString:UIApplicationOpenSettingsURLString]];
        }
        else if (alertView.tag == 300)
        {
            //This will open particular app location settings
            [[UIApplication sharedApplication] openURL:[NSURL URLWithString:UIApplicationOpenSettingsURLString]];
        }
    }
}

GLHF!

Full easy copy and paste code built from @ZacBowling's solution (https://stackoverflow.com/a/1535427/2298002)

this will also bring the user to your app settings and allow them to enable immediately

I also added in a solution for checking if location services is enabled (and brings to settings as well)

// check if notification service is enabled
+ (void)checkNotificationServicesEnabled
{
    if (![[UIApplication sharedApplication] isRegisteredForRemoteNotifications])
    {
        UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:@"Notification Services Disabled!"
                                                            message:@"Yo don't mess around bro! Enabling your Notifications allows you to receive important updates"
                                                           delegate:self
                                                  cancelButtonTitle:@"Cancel"
                                                  otherButtonTitles:@"Settings", nil];

        alertView.tag = 300;

        [alertView show];

        return;
    }
}

// check if location service is enabled (ref: https://stackoverflow.com/a/35982887/2298002)
+ (void)checkLocationServicesEnabled
{
    //Checking authorization status
    if (![CLLocationManager locationServicesEnabled] || [CLLocationManager authorizationStatus] == kCLAuthorizationStatusDenied)
    {

        UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:@"Location Services Disabled!"
                                                            message:@"You need to enable your GPS location right now!!"
                                                           delegate:self
                                                  cancelButtonTitle:@"Cancel"
                                                  otherButtonTitles:@"Settings", nil];

        //TODO if user has not given permission to device
        if (![CLLocationManager locationServicesEnabled])
        {
            alertView.tag = 100;
        }
        //TODO if user has not given permission to particular app
        else
        {
            alertView.tag = 200;
        }

        [alertView show];

        return;
    }
}

// handle bringing user to settings for each
+ (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex
{

    if(buttonIndex == 0)// Cancel button pressed
    {
        //TODO for cancel
    }
    else if(buttonIndex == 1)// Settings button pressed.
    {
        if (alertView.tag == 100)
        {
            //This will open ios devices location settings
            [[UIApplication sharedApplication] openURL:[NSURL URLWithString:@"prefs:root=LOCATION_SERVICES"]];
        }
        else if (alertView.tag == 200)
        {
            //This will open particular app location settings
            [[UIApplication sharedApplication] openURL:[NSURL URLWithString:UIApplicationOpenSettingsURLString]];
        }
        else if (alertView.tag == 300)
        {
            //This will open particular app location settings
            [[UIApplication sharedApplication] openURL:[NSURL URLWithString:UIApplicationOpenSettingsURLString]];
        }
    }
}

GLHF!

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文