Определите на iPhone, если пользователь включил push-уведомления - PullRequest
205 голосов
/ 08 октября 2009

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

Ответы [ 19 ]

300 голосов
/ 08 октября 2009

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

Например:

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

iOS8 и выше:

[[UIApplication sharedApplication] isRegisteredForRemoteNotifications]
99 голосов
/ 28 марта 2012

квантомотато выпуск:

Где types определяется как

UIRemoteNotificationType types = [[UIApplication sharedApplication] enabledRemoteNotificationTypes];

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

if (types & UIRemoteNotificationTypeAlert)

вместо

if (types == UIRemoteNotificationTypeNone) 

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

53 голосов
/ 20 сентября 2014

В последней версии 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;
}
51 голосов
/ 01 октября 2015

Обновлен код для 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.

}

просто проверьте, включены ли Push-уведомления

    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
    }
33 голосов
/ 09 февраля 2015

Ниже вы найдете полный пример, который охватывает как 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");
25 голосов
/ 23 сентября 2016

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()
        }
    }
}
17 голосов
/ 05 марта 2015

Пытаясь поддерживать 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;
}
15 голосов
/ 25 марта 2016

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

Учтите это:

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

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

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

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

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

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

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

Можно сделать несколько предположений:

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

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

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;
}
5 голосов
/ 04 февраля 2015

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

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

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

...