Pergunta

Estou procurando uma maneira de determinar se o usuário ativou ou desativou, por meio de configurações, suas notificações push para meu aplicativo.

Foi útil?

Solução

Ligar enabledRemoteNotificationsTypes e verifique a máscara.

Por exemplo:

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

iOS8 e acima:

[[UIApplication sharedApplication] isRegisteredForRemoteNotifications]

Outras dicas

A questão do QuantumpoTato:

Onde types É dado por

UIRemoteNotificationType types = [[UIApplication sharedApplication] enabledRemoteNotificationTypes];

Pode -se usar

if (types & UIRemoteNotificationTypeAlert)

ao invés de

if (types == UIRemoteNotificationTypeNone) 

Permitirá verificar apenas se as notificações estão ativadas (e não se preocupe com sons, crachás, centro de notificação etc.). A primeira linha de código (types & UIRemoteNotificationTypeAlert) retornará YES Se "estilo de alerta" estiver definido como "banners" ou "alertas", e NO Se o "estilo de alerta" estiver definido como "nenhum", independentemente de outras configurações.

Na versão mais recente do iOS, esse método agora está preso. Para apoiar o uso do iOS 7 e 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;
}

Código atualizado para 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()
}

Código para Swift3.0, iOS10

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

De iOS9, Swift 2.0 uiremotenotificationType está depreciado, use o código seguinte

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.

}

Basta verificar se as notificações push estão ativadas

    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
    }

Abaixo, você encontrará um exemplo completo que cobre o iOS8 e o iOS7 (e as versões mais baixas). Observe que antes do iOS8 você não pode distinguir entre "notificações remotas desativadas" e "apenas Vista na tela de bloqueio ativado".

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
    }

Versão observável rxswift para 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()
        }
    }
}

Ao tentar apoiar o iOS8 e o Lower, não tive muita sorte usando isRegisteredForRemoteNotifications Como Kevin sugeriu. Em vez disso, usei currentUserNotificationSettings, o que funcionou muito bem nos meus testes.

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

Infelizmente nenhuma dessas soluções fornecidas verdade Resolva o problema porque, no final do dia, as APIs faltam seriamente quando se trata de fornecer as informações pertinentes. Você pode fazer algumas palpites, no entanto, usando currentUserNotificationSettings (iOS8+) simplesmente não é suficiente em sua forma atual para realmente responder à pergunta. Embora muitas soluções aqui pareçam sugerir que isso ou isRegisteredForRemoteNotifications é mais uma resposta definitiva que realmente não é.

Considere isto:

com isRegisteredForRemoteNotifications Documentação estados:

Retorna Sim Se o aplicativo estiver registrado atualmente para notificações remotas, levando em consideração qualquer configuração em todo o sistema ...

No entanto, se você jogar um simplesmente NSLog No seu delegado de aplicativo para observar o comportamento, fica claro que isso não se comporta da maneira como estamos antecipando que ele funcionará. Na verdade, ele pertence diretamente a notificações remotas tendo sido ativadas para este aplicativo/dispositivo. Uma vez ativado pela primeira vez, isso sempre retornará YES. Mesmo desligá -los em ambientes (notificações) ainda resultará nessa retorna YES Isso ocorre porque, a partir do iOS8, um aplicativo pode se registrar para notificações remotas e até enviar a um dispositivo sem que o usuário tenha notificações ativadas, elas podem não fazer alertas, crachás e som sem que o usuário o ativasse. As notificações silenciosas são um bom exemplo de algo que você pode continuar fazendo, mesmo com notificações desligadas.

Tão longe quanto currentUserNotificationSettings Indica uma das quatro coisas:

Os alertas estão em crachás no som que não estão em diante.

Isso não fornece absolutamente nenhuma indicação sobre os outros fatores ou a própria troca de notificação.

De fato, um usuário pode desativar crachás, som e alertas, mas ainda assim exibe na tela de bloqueio ou no centro de notificação. Esse usuário ainda deve estar recebendo notificações push e poder vê -las na tela de bloqueio e no centro de notificação. Eles têm o interruptor de notificação. MAS currentUserNotificationSettings retornará: UIUserNotificationTypeNone nesse caso. Isso não é realmente indicativo das configurações reais dos usuários.

Algumas suposições que se pode fazer:

  • E se isRegisteredForRemoteNotifications é NO Então você pode assumir que este dispositivo nunca se registrou com sucesso para notificações remotas.
  • Após a primeira vez em registrar notificações remotas, um retorno de chamada para application:didRegisterUserNotificationSettings: é feito contendo configurações de notificação do usuário no momento, pois esta é a primeira vez que um usuário é registrado nas configurações deve Indique o que o usuário selecionou em termos da solicitação de permissão. Se as configurações equivalem a qualquer outra coisa senão: UIUserNotificationTypeNone Em seguida, foi concedida permissão push, caso contrário, foi recusado. A razão para isso é que, a partir do momento em que você inicia o processo de registro remoto, o usuário só tem a capacidade de aceitar ou recusar, com as configurações iniciais de uma aceitação sendo as configurações que você configura durante o processo de registro.

Para concluir a resposta, poderia funcionar algo assim ...

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: Isso não está certo. Como essas são coisas de um pouco, isso não funciona com um switch, então acabei usando isso:

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

Para iOS7 e antes de você realmente usar enabledRemoteNotificationTypes e verifique se é igual (ou não é igual dependendo do que você deseja) UIRemoteNotificationTypeNone.

No entanto, para iOS8, é não sempre o suficiente para verificar apenas com isRegisteredForRemoteNotifications Tanto estado acima. Você também deve verificar se application.currentUserNotificationSettings.types é igual (ou não é igual dependendo do que você deseja) UIUserNotificationTypeNone!

isRegisteredForRemoteNotifications pode retornar verdadeiro, embora currentUserNotificationSettings.types retorna UIUserNotificationTypeNone.

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

Aqui obtemos o UIRemotenotificationType da UIApplication. Representa o estado de notificação push deste aplicativo no cenário, do que você pode verificar seu tipo facilmente

Tento oferecer suporte ao iOS 10 e superior usando a solução fornecida por @Shaheen Ghiassy, ​​mas encontro um problema de privação enabledRemoteNotificationTypes.Então, a solução que encontro usando isRegisteredForRemoteNotifications em vez de enabledRemoteNotificationTypes que foi descontinuado no iOS 8.Abaixo está minha solução atualizada que funcionou perfeitamente para mim:

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

E podemos chamar essa função facilmente e acessar seu Bool valor e pode convertê-lo no valor da string desta forma:

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

Espero que isso ajude os outros também :) Codificação feliz.

iOS8+ (objetivo 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;
    }
}];

Embora a resposta de Zac tenha sido perfeitamente correta até o iOS 7, ela mudou desde que o iOS 8 chegou. Porque EnabledRemoteNotificationTypes foi depreciado do iOS 8 em diante. Para iOS 8 e mais tarde, você precisa usar isregisterEdForremotenotificações.

  • para iOS 7 e antes -> Use EnableDRemoteNotificationTypes
  • para iOS 8 e mais tarde -> Use isregisterEdformotenotificações.

este Swifty Solução funcionou bem para mim (iOS8+),

Método:

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

Uso:

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

Ref

ré:

isto está certo

if (types & UIRemoteNotificationTypeAlert)

Mas a seguir também está correto! (Como uiremotenotificação TypeNona é 0)

if (types == UIRemoteNotificationTypeNone) 

Veja o seguinte

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

Veja como fazer isso em xamarin.ios.

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

Se você está apoiando o iOS 10+, vá apenas com o método UnuserNotificationCenter.

Em Xamarin, toda a solução acima não funciona para mim. Isso é o que eu uso: em vez disso:

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

Também está recebendo uma atualização ao vivo depois de alterar o status de notificação nas configurações.

Código de cópia e pasta fácil e fácil construído a partir da solução de @Zacbowling (https://stackoverflow.com/a/1535427/2298002)

Isso também trará o usuário às configurações do seu aplicativo e permitirá que eles possam ativar imediatamente

Eu também adicionei uma solução para verificar se os serviços de localização estiverem ativados (e também traga configurações)

// 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!

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top