Réponses:
Appelez enabledRemoteNotificationsTypes
et vérifiez le masque.
Par exemple:
UIRemoteNotificationType types = [[UIApplication sharedApplication] enabledRemoteNotificationTypes];
if (types == UIRemoteNotificationTypeNone)
// blah blah blah
iOS8 et supérieur:
[[UIApplication sharedApplication] isRegisteredForRemoteNotifications]
iOS 8
et plus est incorrecte car elle vérifie uniquement si l'utilisateur s'est inscrit pour la notification à distance. Selon la documentation:This method reflects only the successful completion of the remote registration process that begins when you call the registerForRemoteNotifications method. This method does not reflect whether remote notifications are actually available due to connectivity issues. The value returned by this method takes into account the user’s preferences for receiving remote notifications.
[[UIApplication sharedApplication] currentUserNotificationSettings];
problème de quantumpotato:
Où 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
) sera renvoyée 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.
grantedSettings.types.contains(notificationType)
Dans la dernière version d'iOS, cette méthode est désormais obsolète. Pour prendre en charge 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;
}
UserNotifications
. Malheureusement, je n'ai pas de réponse complète maintenant.
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.
}
vérifiez simplement 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
}
Vous trouverez ci-dessous un exemple complet qui couvre à la fois iOS8 et iOS7 (et les versions inférieures). Veuillez noter qu'avant iOS8, vous ne pouviez pas faire la distinction entre «notifications à distance désactivées» et «uniquement Afficher dans l'écran de verrouillage 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");
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 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()
}
}
}
getNotificationSettings(...)
est asynchrone donc le retour à l'intérieur sera ignoré
En essayant de prendre en charge iOS8 et inférieur, je n'ai pas eu beaucoup de chance à utiliser isRegisteredForRemoteNotifications
comme Kevin l'a suggéré. Au lieu de cela, j'ai utilisé currentUserNotificationSettings
, ce qui a très bien fonctionné dans 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;
}
isEnabled = NO;
dans vos if
cas, il n'est pas nécessaire car il a été initialisé commeNO
Malheureusement, aucune de ces solutions fournies ne résout vraiment le problème car, en fin de compte, les API manquent sérieusement lorsqu'il s'agit de fournir les informations pertinentes. Vous pouvez faire quelques suppositions mais l'utilisation currentUserNotificationSettings
(iOS8 +) n'est tout simplement pas suffisante dans sa forme actuelle pour vraiment répondre à la question. Bien que beaucoup de solutions semblent suggérer que ce soit ou isRegisteredForRemoteNotifications
est plutôt une réponse définitive, ce n'est vraiment pas le cas.
Considère ceci:
avec la isRegisteredForRemoteNotifications
documentation indique:
Renvoie OUI si l'application est actuellement enregistrée pour les notifications à distance, en tenant compte des paramètres à l'échelle du système ...
Cependant, si vous jetez simplement NSLog
un délégué dans votre application pour observer le comportement, il est clair que cela ne se comporte pas de la façon dont nous prévoyons que cela fonctionnera. Il s'agit en fait directement des notifications à distance ayant été activées pour cette application / cet appareil. Une fois activé pour la première fois, il reviendra toujours YES
. Même les désactiver dans les paramètres (notifications) entraînera toujours ce retour YES
car, à partir d'iOS8, une application peut s'enregistrer pour les notifications à distance et même envoyer vers un appareil sans que l'utilisateur ait activé les notifications, il se peut qu'il ne fasse pas d'alertes, Badges et sons sans que l'utilisateur n'active cela. Les notifications silencieuses sont un bon exemple de quelque chose que vous pouvez continuer à faire même avec des notifications désactivées.
Pour autant currentUserNotificationSettings
qu'il indique l'une des quatre choses:
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 le commutateur de notification lui-même.
Un utilisateur peut en effet désactiver les badges, le son et les alertes, mais les afficher sur l'écran de verrouillage ou dans le centre de notification. Cet utilisateur doit toujours recevoir des notifications push et pouvoir les voir à la fois sur l'écran de verrouillage et dans le centre de notifications. Ils ont le commutateur de notification activé. MAIS currentUserNotificationSettings
reviendra: UIUserNotificationTypeNone
dans ce cas. Ce n'est pas vraiment indicatif des paramètres réels des utilisateurs.
Quelques suppositions que l'on peut faire:
isRegisteredForRemoteNotifications
c'est le cas, NO
vous pouvez supposer que cet appareil ne s'est jamais enregistré avec succès pour les notifications à distance.application:didRegisterUserNotificationSettings:
est effectué contenant les paramètres de notification de l'utilisateur à ce moment car c'est la première fois qu'un utilisateur est enregistré, les paramètres doivent indiquer ce que l'utilisateur a sélectionné en termes de demande d'autorisation. Si les paramètres correspondent à autre chose que: UIUserNotificationTypeNone
alors l'autorisation push a été accordée, sinon elle a été refusée. La raison en est qu'à partir du moment où vous commencez le processus d'enregistrement à distance, l'utilisateur n'a que la possibilité d'accepter ou de refuser, les paramètres initiaux d'une acceptation étant les paramètres que vous avez définis pendant le processus d'enregistrement.Pour compléter la réponse, cela pourrait fonctionner quelque chose comme ça ...
UIRemoteNotificationType types = [[UIApplication sharedApplication] enabledRemoteNotificationTypes];
switch (types) {
case UIRemoteNotificationTypeAlert:
case UIRemoteNotificationTypeBadge:
// For enabled code
break;
case UIRemoteNotificationTypeSound:
case UIRemoteNotificationTypeNone:
default:
// For disabled code
break;
}
modifier: Ce n'est pas juste. comme ce sont des trucs au niveau des bits, cela ne fonctionnera pas avec un commutateur, j'ai donc 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;
}
Pour iOS7 et avant, vous devez en effet utiliser enabledRemoteNotificationTypes
et vérifier s'il est égal (ou différent en fonction de ce que vous voulez) UIRemoteNotificationTypeNone
.
Cependant, pour iOS8, il ne suffit pas toujours de vérifier avec isRegisteredForRemoteNotifications
autant d'états ci-dessus. Vous devriez également vérifier si application.currentUserNotificationSettings.types
égal (ou différent selon ce que vous voulez) UIUserNotificationTypeNone
!
isRegisteredForRemoteNotifications
pourrait retourner vrai même si currentUserNotificationSettings.types
retourne UIUserNotificationTypeNone
.
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;
}
}];
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 la notification push de cette application dans le paramètre, que vous pouvez vérifier facilement sur son type
J'essaie de prendre en charge iOS 10 et supérieur en utilisant la solution fournie par @Shaheen Ghiassy mais je trouve un problème de privation enabledRemoteNotificationTypes
. Donc, la solution que je trouve en utilisant isRegisteredForRemoteNotifications
au lieu de enabledRemoteNotificationTypes
celle obsolète dans iOS 8. Voici ma solution mise à jour qui a parfaitement fonctionné 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 Bool
valeur et la convertir en valeur de chaîne par ceci:
NSString *str = [self notificationServicesEnabled] ? @"YES" : @"NO";
J'espère que cela aidera les autres aussi :) Bon codage.
Bien que la réponse de Zac était parfaitement correcte jusqu'à iOS 7, elle a changé depuis l'arrivée d'iOS 8. Parce que enabledRemoteNotificationTypes est obsolète à partir d'iOS 8. Pour iOS 8 et versions ultérieures, vous devez utiliser isRegisteredForRemoteNotifications .
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)
}
}
}
Utilisation :
isNotificationEnabled { (isEnabled) in
if isEnabled{
print("Push notification enabled")
}else{
print("Push notification not enabled")
}
}
ré:
c'est correct
if (types & UIRemoteNotificationTypeAlert)
mais ce qui suit est correct aussi! (comme UIRemoteNotificationTypeNone est 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
Voici comment procéder 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.
Dans Xamarin, la solution ci-dessus ne fonctionne 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 également une mise à jour en direct après avoir modifié l'état de la notification dans les paramètres.
Copiez et collez du code facilement et entièrement à partir de la solution de @ ZacBowling ( https://stackoverflow.com/a/1535427/2298002 )
cela amènera également l'utilisateur aux paramètres de votre application et lui permettra d'activer immédiatement
J'ai également ajouté une solution pour vérifier si les services de localisation sont activés (et apporte également des paramètres)
// 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]];
}
}
}
GL HF!