Определить на iPhone, если пользователь включил push-уведомления



Я ищу способ определить, если пользователь, с помощью настроек, включен или отключен их уведомления толчка для моего приложения.

676   19  

19 ответов:

вызов enabledRemoteNotificationsTypes и проверьте маску.

например:

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

iOS8 и выше:

[[UIApplication sharedApplication] isRegisteredForRemoteNotifications]

Я не могу комментировать (недостаточно репутации), но вопрос re: quantumpotato:

здесь types дано

UIRemoteNotificationType types = [[UIApplication sharedApplication] enabledRemoteNotificationTypes];

можно использовать

if (types & UIRemoteNotificationTypeAlert)

вместо

if (types == UIRemoteNotificationTypeNone) 

позволит вам проверить, включены ли уведомления (и не беспокойтесь о звуках, значках, центре уведомлений и т. д.). Первая строка кода (types & UIRemoteNotificationTypeAlert) возвращает YES если "стиль оповещения" установлен в "баннеры " или" оповещения", и NO если "стиль оповещения" является значение "нет", независимо от других параметров.

в последней версии 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;
}

обновленный код для 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
    }

ниже вы найдете полный пример, который охватывает как iOS8, так и iOS7 (и более низкие версии). Обратите внимание, что до iOS8 вы не можете различать "удаленные уведомления отключены" и " только просмотр в lockscreen включено".

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
    }

RxSwift наблюдаемая версия для 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()
        }
    }
}

в попытке поддержать как 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;
}

к сожалению, ни одно из этих решений действительно решить проблему, потому что в конце дня API серьезно не хватает, когда дело доходит до предоставления соответствующей информации. Вы можете сделать несколько предположений, однако с помощью currentUserNotificationSettings (iOS8+) просто недостаточно в его нынешнем виде, чтобы действительно ответить на вопрос. Хотя многие решения здесь, похоже, предполагают, что либо это, либо isRegisteredForRemoteNotifications это скорее окончательный ответ, это действительно так не.

рассмотрим следующий пример:

С isRegisteredForRemoteNotifications документация гласит:

возвращает да, если приложение в настоящее время зарегистрировано для удаленных уведомлений, принимая во внимание любые общесистемные настройки...

однако если вы бросаете просто NSLog в вашем делегате приложения, чтобы наблюдать за поведением ясно, что это не ведет себя так, как мы ожидаем, что это будет работать. Это на самом деле относится непосредственно к удаленным уведомлениям будучи активирован для этого приложения / устройства. После активации в первый раз это всегда будет возвращать YES. Даже отключение их в настройках (уведомления) все равно приведет к этому возвращению YES это потому, что, начиная с iOS8, приложение может регистрироваться для удаленных уведомлений и даже отправлять на устройство без пользователя с включенными уведомлениями, они просто не могут делать оповещения, значки и звук без включения пользователя. Тихие уведомления являются хорошим примером того, что вы можете продолжайте делать даже с отключенными уведомлениями.

насколько currentUserNotificationSettings Он указывает на одну из четырех вещей:

оповещения о Значки на Звук на Ни один не включен.

это не дает вам абсолютно никаких указаний на другие факторы или сам переключатель уведомлений.

пользователь может на самом деле отключить значки, звук и оповещения, но по-прежнему показывать на экране блокировки или в Центре уведомлений. Этот пользователь должен по-прежнему получать push уведомления и иметь возможность видеть их обоих на экране блокировки и в Центре уведомлений. У них есть переключатель уведомлений. Но currentUserNotificationSettings вернутся: UIUserNotificationTypeNone в этом случае. Это не совсем указывает на фактические настройки пользователей.

несколько догадок можно сделать:

  • если isRegisteredForRemoteNotifications и NO тогда вы можете предположить, что это устройство никогда не было успешно зарегистрировано для удаленных уведомлений.
  • после первой регистрации для удаленные уведомления обратный вызов application:didRegisterUserNotificationSettings: сделано содержащий настройки уведомления Пользователя в это время, так как это первый раз, когда пользователь был зарегистрирован настройки должны укажите, что пользователь выбрал с точки зрения запроса разрешения. Если настройки приравниваются к чему-либо, кроме: UIUserNotificationTypeNone затем разрешение push было предоставлено, в противном случае оно было отклонено. Причина этого заключается в том, что с момента начала процесса удаленной регистрации пользователь имеет возможность чтобы принять или отклонить с первоначального параметров принимаются параметры настройки при регистрации.

чтобы завершить ответ, он может работать примерно так...

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: это не правильно. поскольку это бит-мудрый материал, он не будет работать с переключателем, поэтому я закончил использовать это:

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

для iOS7 и прежде чем вы действительно должны использовать enabledRemoteNotificationTypes и проверить, если он равен (или не равен в зависимости от того, что вы хотите)UIRemoteNotificationTypeNone.

однако для iOS8 это не всегда достаточно, чтобы проверить только с isRegisteredForRemoteNotifications как многие государства выше. Вы также должны проверить, если application.currentUserNotificationSettings.types равно (или не равно в зависимости от того, что вы хотите) UIUserNotificationTypeNone!

isRegisteredForRemoteNotifications может вернуть true, даже если currentUserNotificationSettings.types возвращает UIUserNotificationTypeNone.

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

здесь мы получаем UIRemoteNotificationType из UIApplication. Он представляет собой состояние push-уведомления этого приложения в настройках, чем вы можете легко проверить его тип

Я пытаюсь поддерживать iOS 10 и выше, используя решение, предоставляемое @Shaheen Ghiassy, но найти проблему лишения enabledRemoteNotificationTypes. Итак, решение я нахожу с помощью isRegisteredForRemoteNotifications вместо enabledRemoteNotificationTypes который устарел в iOS 8. Ниже мое обновленное решение, которое отлично работает для меня:

- (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";

надеюсь, что это поможет другим тоже :) Счастливый кодирование.

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

хотя ответ Зака был совершенно правильным до iOS 7,он изменился с момента появления iOS 8. Потому что enabledRemoteNotificationTypes была удалена с iOS 8 и выше. Для iOS 8 и более поздних версий необходимо использовать isRegisteredForRemoteNotifications.

  • для iOS 7 и до -- > используйте enabledRemoteNotificationTypes
  • для iOS 8 и более поздних версий -- > используйте isRegisteredForRemoteNotifications.

этой тренер решение работало хорошо для меня (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")
            }
        }

Ref

re:

это правильно

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

вот как это сделать в Xamarin.усвн.

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

Если вы поддерживаете iOS 10+, используйте только метод UNUserNotificationCenter.

в Xamarin, все выше решение не работает для меня. Вот что я использую вместо этого:

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

Это обновление также после того как вы изменили статус уведомлений в настройках.

полное легкое копирование и вставка кода, построенного из решения @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!

Comments

    Ничего не найдено.