web-dev-qa-db-fra.com

Déterminer sur iPhone si l'utilisateur a activé les notifications Push

Je cherche un moyen de déterminer si l'utilisateur a, via ses paramètres, activé ou désactivé ses notifications Push pour mon application.

201
Kevin

Appelez enabledRemoteNotificationsTypes et vérifiez le masque.

Par exemple: 

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

iOS8 et au-dessus:

[[UIApplication sharedApplication] isRegisteredForRemoteNotifications]
300
Zac Bowling

Je ne peux pas commenter (pas assez de réputation), mais re: le problème de quantumpotato:

types est donné par

UIRemoteNotificationType types = [[UIApplication sharedApplication] enabledRemoteNotificationTypes];

on peut utiliser

if (types & UIRemoteNotificationTypeAlert)

au lieu de 

if (types == UIRemoteNotificationTypeNone) 

vous permettra de vérifier uniquement si les notifications sont activées (et ne vous inquiétez pas des sons, des badges, du centre de notification, etc.). La première ligne de code (types & UIRemoteNotificationTypeAlert) renverra YES si "Style d'alerte" est défini sur "Bannières" ou "Alertes" et NO si "Style d'alerte" est défini sur "Aucun", quels que soient les autres paramètres.

99
Tim Camber

Dans la dernière version d'iOS, cette méthode est maintenant obsolète. Pour prendre en charge à la fois iOS 7 et iOS 8, utilisez:

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;
}
53
Kevin Sylvestre

Code mis à jour pour 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 pour Swift3.0, iOS10

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

Depuis iOS9, Swift 2.0 UIRemoteNotificationType est obsolète, utilisez le code suivant

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.

}

il suffit de vérifier si les notifications Push sont activées

    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
    }
48
ViJay Avhad

Vous trouverez ci-dessous un exemple complet couvrant à la fois iOS8 et iOS7 (et versions inférieures). Veuillez noter qu'avant iOS8, vous ne pouviez pas faire la distinction entre "notifications à distance désactivées" et "uniquement Afficher en lockscreen activé".

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");
33
tilo

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
    }

Version observable de RxSwift pour 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()
        }
    }
}
24
Adam Smaka

En essayant de prendre en charge iOS8 et les versions antérieures, je n’ai pas eu beaucoup de chance d’utiliser isRegisteredForRemoteNotifications, comme l’a suggéré Kevin. Au lieu de cela, j'ai utilisé currentUserNotificationSettings, qui a très bien fonctionné lors de mes tests.

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

Malheureusement, aucune de ces solutions fournies vraiment ne résout le problème car, en fin de compte, les API manquent cruellement lorsqu'il s'agit de fournir les informations pertinentes. Vous pouvez faire quelques suppositions. Cependant, utiliser currentUserNotificationSettings (iOS8 +) ne suffit pas dans sa forme actuelle pour vraiment répondre à la question. Bien que beaucoup de solutions semblent suggérer que soit cela, soit isRegisteredForRemoteNotifications soit une réponse définitive, ce n’est vraiment pas le cas.

Considère ceci:

avec isRegisteredForRemoteNotifications documentation indique:

Renvoie OUI si l'application est actuellement enregistrée pour les notifications à distance, en tenant compte des paramètres du système ...

Cependant, si vous jetez simplement NSLog dans le délégué de votre application pour observer le comportement, il est clair que cela ne se comporte pas de la manière dont nous prévoyons qu'il fonctionnera. En fait, cela concerne directement les notifications à distance ayant été activées pour cette application/appareil. Une fois activé pour la première fois, il retournera toujours YES. Même si vous les désactivez dans les paramètres (notifications), le résultat retournera toujours YES car, à partir de iOS8, une application peut s'inscrire pour les notifications distantes et même être envoyée à un appareil sans que l'utilisateur ait activé les notifications. , Badges et son sans que l’utilisateur ne l’active. Les notifications silencieuses sont un bon exemple de ce que vous pouvez continuer à faire même si les notifications sont désactivées.

En ce qui concerne currentUserNotificationSettings, il indique l'une des quatre choses suivantes:

Les alertes sont activées Les badges sont activés Le son est activé Aucun n'est activé.

Cela ne vous donne absolument aucune indication sur les autres facteurs ou sur le commutateur de notification lui-même.

Un utilisateur peut en effet désactiver les badges, le son et les alertes, mais doit quand même afficher l’écran de verrouillage ou le centre de notification. Cet utilisateur devrait toujours recevoir des notifications Push et pouvoir les voir à la fois sur l'écran de verrouillage et dans le centre de notification. Ils ont la notification allumée. MAIS currentUserNotificationSettings retournera: UIUserNotificationTypeNone dans ce cas. Ce n'est pas vraiment indicatif des paramètres réels des utilisateurs.

Quelques suppositions peuvent être faites:

  • si isRegisteredForRemoteNotifications est NO, vous pouvez donc supposer que ce périphérique n'a jamais été enregistré avec succès pour les notifications à distance.
  • après la première inscription aux notifications à distance, un rappel à application:didRegisterUserNotificationSettings: contenant les paramètres de notification de l'utilisateur est effectué, car il s'agit de la première fois qu'un utilisateur est enregistré, les paramètres doivent indiquer ce que l'utilisateur a sélectionné pour l'autorisation. demande. Si les paramètres correspondent à autre chose que: UIUserNotificationTypeNone, l'autorisation Push a été accordée, sinon elle a été refusée. En effet, à partir du moment où vous démarrez le processus d’enregistrement à distance, l’utilisateur n’a plus que la possibilité d’accepter ou de refuser, les paramètres initiaux d’une acceptation étant ceux définis lors du processus d’enregistrement.
15
iYorke

Pour compléter la réponse, cela pourrait fonctionner comme ceci ...

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: Ce n'est pas correct. comme ce sont des trucs en bits, ça ne marchera pas avec un commutateur, alors j'ai fini par utiliser ceci:

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

Pour iOS7 et les versions antérieures, vous devriez en effet utiliser enabledRemoteNotificationTypes et vérifier si la valeur est égale (ou différente selon ce que vous voulez) à UIRemoteNotificationTypeNone.

Cependant, pour iOS8, il ne faut toujours pas toujours vérifier avec isRegisteredForRemoteNotifications autant d’états que ci-dessus. Vous devriez également vérifier si application.currentUserNotificationSettings.types est égal (ou différent selon ce que vous voulez) UIUserNotificationTypeNone!

isRegisteredForRemoteNotifications peut retourner true même si currentUserNotificationSettings.types renvoie UIUserNotificationTypeNone.

5
Peter Verhage

iOS8 + (objectif 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;
    }
}];
4
Ofir Malachi
UIRemoteNotificationType types = [[UIApplication sharedApplication] enabledRemoteNotificationTypes];
if (types & UIRemoteNotificationTypeAlert)
    // blah blah blah
{
    NSLog(@"Notification Enabled");
}
else
{
    NSLog(@"Notification not enabled");
}

Ici, nous obtenons le UIRemoteNotificationType de UIApplication. Il représente l'état de notification Push de cette application dans le paramètre, que vous pouvez vérifier facilement sur son type

4
Hossam Ghareeb

J'essaie de prendre en charge iOS 10 et les versions ultérieures à l'aide de la solution fournie par @Shaheen Ghiassy, ​​mais trouve un problème de privation enabledRemoteNotificationTypes Donc, la solution que je trouve en utilisant isRegisteredForRemoteNotifications au lieu de enabledRemoteNotificationTypes qui est obsolète dans iOS 8. Voici la solution mise à jour qui fonctionne parfaitement pour moi:

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

Et nous pouvons appeler cette fonction facilement et accéder à sa valeur Bool et la convertir en valeur de chaîne de la manière suivante:

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

J'espère que cela aidera les autres aussi:) Happy coding.

4
Irfan

Bien que la réponse de Zac soit parfaitement correcte jusqu'à iOS 7, elle a changé depuis l'arrivée de iOS 8. Parce que enabledRemoteNotificationTypes est obsolète à partir de iOS 8. Pour iOS 8 et versions ultérieures, vous devez utiliser isRegisteredForRemoteNotifications .

  • pour iOS 7 et versions antérieures -> Utilisez enabledRemoteNotificationTypes 
  • pour iOS 8 et versions ultérieures -> Utilisez isRegisteredForRemoteNotifications.
3

Cette solution Swifty a bien fonctionné pour moi (iOS8 +),

Méthode

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

Réf

1
Zaid Pathan

Dans Xamarin, toutes les solutions ci-dessus ne fonctionnent pas pour moi ... C'est ce que j'utilise à la place:

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

Il reçoit une mise à jour en direct également après avoir modifié le statut de notification dans les paramètres.

0
mr5

ré:

c'est correct

if (types & UIRemoteNotificationTypeAlert)

mais suivre est correct aussi! (comme UIRemoteNotificationTypeNone vaut 0)

if (types == UIRemoteNotificationTypeNone) 

voir ce qui suit

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
0
wavespread

Voici comment faire cela dans Xamarin.ios.

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

Si vous prenez en charge iOS 10+, utilisez uniquement la méthode UNUserNotificationCenter.

0
Sune Kjærgård