Pregunta

Estoy buscando una manera de determinar si el usuario tiene, a través de la configuración, habilitado o deshabilitado sus notificaciones push para mi aplicación.

¿Fue útil?

Solución

enabledRemoteNotificationsTypes de llamadas y comprobar la máscara.

Por ejemplo:

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

iOS8 y superior:

[[UIApplication sharedApplication] isRegisteredForRemoteNotifications]

Otros consejos

tema de quantumpotato:

Donde types está dada por

UIRemoteNotificationType types = [[UIApplication sharedApplication] enabledRemoteNotificationTypes];

Uno puede usar

if (types & UIRemoteNotificationTypeAlert)

en lugar de

if (types == UIRemoteNotificationTypeNone) 

le permitirá comprobar solamente si las notificaciones están activadas (y no se preocupan de sonidos, insignias, centro de notificaciones, etc.). La primera línea de código (types & UIRemoteNotificationTypeAlert) devolverá YES si "estilo de alerta" se establece en "banners" o "Alertas", y NO si "estilo de alerta" está ajustado en "None", independientemente de otros ajustes.

En la última versión de iOS ahora es obsoleto este método. Para apoyar ambos iOS 7 y 8 iOS uso:

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 actualizado 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 de swift3.0, iOS10

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

Desde iOS9, SWIFT 2.0 UIRemoteNotificationType está en desuso, el uso siguiente código

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.

}
  

simplemente comprobar si las notificaciones push están habilitados

    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
    }

A continuación encontrará un ejemplo completo que cubre tanto iOS8 y iOS7 (y versiones anteriores). Tenga en cuenta que antes de iOS8 no se puede distinguir entre "notificaciones remotas desactivado" y "única Ver en pantalla de bloqueo Activado".

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 observable Versión 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()
        }
    }
}

Al tratar de apoyar tanto iOS8 e inferior, que no tenía mucha suerte con isRegisteredForRemoteNotifications como Kevin sugirió. En su lugar he usado currentUserNotificationSettings, que funcionó muy bien en mis pruebas.

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

Por desgracia, ninguna de estas soluciones proporcionadas realmente resuelve el problema, porque al final del día las API faltan en serio cuando se trata de proporcionar la información pertinente. Puede haga algunas conjeturas sin embargo utilizando currentUserNotificationSettings (iOS8 +) simplemente no es suficiente en su forma actual para contestar realmente la pregunta. A pesar de que muchas de las soluciones aquí parecen sugerir que cualquiera que o isRegisteredForRemoteNotifications es más una respuesta definitiva en realidad no lo es.

Considere esto:

con los estados de documentación isRegisteredForRemoteNotifications:

  

Devuelve YES si la aplicación está actualmente registrado para recibir notificaciones remotas, teniendo en cuenta la configuración de todo el sistema ...

Sin embargo, si se lanza un simple NSLog en delegado de la aplicación para observar el comportamiento es evidente que esto no se comportan de la manera en que estamos anticipando que va a funcionar. En realidad, se refiere directamente a las notificaciones remotas de haber sido activados para esta aplicación / dispositivo. Una vez activado por primera vez, esto siempre volverá YES. Incluso apagarlos en Ajustes (notificaciones) se siguen produciendo en este YES devolver esto es porque, a partir de iOS8, una aplicación puede registrarse para recibir avisos remotos e incluso enviar a un dispositivo sin que el usuario haya habilitado notificaciones, simplemente no pueden hacer Alertas , distintivos y de sonido sin que el usuario girando que en. notificaciones silenciosos son un buen ejemplo de algo que puede seguir haciendo incluso con notificaciones desactivadas.

En lo que currentUserNotificationSettings indica uno de cuatro cosas:

Las alertas están en Insignias están El sonido es en Ninguno están encendidas.

Esto le da absolutamente ninguna indicación alguna acerca de los otros factores o el propio interruptor de notificación.

Un usuario puede, de hecho, apague insignias, sonido y alertas, pero todavía tiene demostración en pantalla de bloqueo o en el centro de notificaciones. Este usuario todavía debe recibir las notificaciones push y ser capaz de ver a ambos en la pantalla de bloqueo y en el centro de notificaciones. Tienen el interruptor de notificación en. PERO currentUserNotificationSettings volverá: UIUserNotificationTypeNone en ese caso. Esto no es realmente indicativa de los ajustes reales de los usuarios.

Algunas conjeturas se pueden hacer:

  • Si es isRegisteredForRemoteNotifications NO continuación, se puede asumir que este dispositivo nunca ha registrado con éxito para las notificaciones remotas.
  • después del primer momento de registrarse para recibir notificaciones remotas una devolución de llamada a application:didRegisterUserNotificationSettings: se hace que contiene la configuración de notificaciones de usuario en este momento ya que esta es la primera vez que un usuario se ha registrado la configuración debería indicar lo que el usuario seleccionada en términos de la solicitud de permiso. Si la configuración equivalen a nada que no sea: UIUserNotificationTypeNone a continuación, empuje el permiso fue concedido, de lo contrario, se redujo. La razón de esto es que desde el momento de comenzar el proceso de registro remoto, el usuario sólo tiene la capacidad de aceptar o rechazar, con los ajustes iniciales de una aceptación siendo la configuración que de configuración durante el proceso de registro.

Para completar la respuesta, podría funcionar algo como esto ...

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: Esto no está bien. ya que estas son las cosas bit a bit, lo puedo trabajar con un interruptor, por lo que terminó usando la siguiente:

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

Para iOS7 y antes de que usted debe utilizar efectivamente enabledRemoteNotificationTypes y comprobar si es igual a (o no es igual dependiendo de lo que desee) a UIRemoteNotificationTypeNone.

Sin embargo, para iOS8 es no siempre es suficiente para comprobar solamente con isRegisteredForRemoteNotifications hasta el estado anterior. También debe comprobar si application.currentUserNotificationSettings.types es igual (o no es igual dependiendo de lo que quiere) UIUserNotificationTypeNone!

isRegisteredForRemoteNotifications podría devolver cierto a pesar de que los rendimientos currentUserNotificationSettings.types UIUserNotificationTypeNone.

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

Aquí tenemos la UIRemoteNotificationType de UIApplication. Representa el estado de notificación de inserción de esta aplicación en el entorno, que se puede comprobar en su tipo fácilmente

Trato de apoyar iOS del 10 mediante solución proporciona por @Shaheen Ghiassy pero encuentra cuestión enabledRemoteNotificationTypes privación. Por lo tanto, la solución que encuentro utilizando isRegisteredForRemoteNotifications en lugar de enabledRemoteNotificationTypes la que está desfasada y en iOS 8. A continuación se muestra mi solución actualizada que funcionó a la perfección para mí:

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

Y podemos llamar a esta función con facilidad y estar accediendo a su valor Bool y podemos convertirlo en el valor de cadena por esto:

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

Esperamos que ayude a los demás también :) Feliz de codificación.

  

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

A pesar de la respuesta de Zac era perfectamente correcta hasta iOS 7, que ha cambiado desde iOS 8 llegó. Debido a que enabledRemoteNotificationTypes ha quedado en desuso desde iOS 8 en adelante. Para iOS 8 y versiones posteriores, es necesario utilizar isRegisteredForRemoteNotifications .

  • para iOS 7 y antes de -> Uso enabledRemoteNotificationTypes
  • para iOS 8 y más tarde -.> Use isRegisteredForRemoteNotifications

Este Swifty solución funcionó bien para mí ( 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

re:

esto es correcto

if (types & UIRemoteNotificationTypeAlert)

pero la siguiente es correcta también !(como UIRemoteNotificationTypeNone es 0 )

if (types == UIRemoteNotificationTypeNone) 

ver el siguiente

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

Aquí se explica cómo hacer esto en Xamarin.ios.

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

Si usted está apoyando IOS 10+ ir sólo con el método UNUserNotificationCenter.

En Xamarin, toda la solución anterior no funciona para mí. Esto es lo que uso en su lugar:

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

Se está haciendo una actualización en vivo también después de haber cambiado el estado de la notificación en la configuración.

copia completa fácil y pegar código construido a partir de la solución de @ ZacBowling ( https://stackoverflow.com/a/1535427/2298002)

Esto también traerá al usuario configuración de la aplicación y permitir que permiten inmediatamente

También se ha añadido en una solución para comprobar si los servicios de localización está activado (y trae a los ajustes también)

// 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 bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top