Risposte:
Chiama enabledRemoteNotificationsTypes
e controlla la maschera.
Per esempio:
UIRemoteNotificationType types = [[UIApplication sharedApplication] enabledRemoteNotificationTypes];
if (types == UIRemoteNotificationTypeNone)
// blah blah blah
iOS8 e versioni successive:
[[UIApplication sharedApplication] isRegisteredForRemoteNotifications]
iOS 8
e successive è errata perché controlla solo se l'utente si è registrato per la notifica remota. Secondo la documentazione: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];
problema di quantumpotato:
Dove types
viene dato da
UIRemoteNotificationType types = [[UIApplication sharedApplication] enabledRemoteNotificationTypes];
si può usare
if (types & UIRemoteNotificationTypeAlert)
invece di
if (types == UIRemoteNotificationTypeNone)
ti consentirà di verificare solo se le notifiche sono abilitate (e non preoccuparti di suoni, badge, centro notifiche, ecc.). La prima riga di codice ( types & UIRemoteNotificationTypeAlert
) verrà restituita YES
se "Stile avviso" è impostato su "Banner" o "Avvisi" e NO
se "Stile avviso" è impostato su "Nessuno", indipendentemente da altre impostazioni.
grantedSettings.types.contains(notificationType)
Nell'ultima versione di iOS questo metodo è ora obsoleto. Per supportare sia iOS 7 che iOS 8 utilizzare:
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
. Non ho una risposta completa ora, sfortunatamente.
Codice aggiornato per 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()
}
Codice per swift3.0, iOS10
let isRegisteredForRemoteNotifications = UIApplication.shared.isRegisteredForRemoteNotifications
if isRegisteredForRemoteNotifications {
// User is registered for notification
} else {
// Show alert user is not registered for notification
}
Da iOS9, swift 2.0 UIRemoteNotificationType è obsoleto, utilizzare il codice seguente
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.
}
controlla semplicemente se le notifiche push sono abilitate
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
}
Di seguito troverai un esempio completo che copre sia iOS8 che iOS7 (e versioni precedenti). Prima di iOS8 non è possibile distinguere tra "notifiche remote disabilitate" e " Visualizza solo nella schermata di blocco abilitata".
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
}
Versione osservabile RxSwift per 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(...)
è asincrono, quindi il ritorno all'interno sarà ignorato
Nel tentativo di supportare sia iOS8 che inferiore, non ho avuto molta fortuna usando isRegisteredForRemoteNotifications
come suggerito Kevin. Invece ho usato currentUserNotificationSettings
, che ha funzionato benissimo nei miei test.
+ (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;
nei tuoi if
casi non è necessario in quanto è stato inizializzato comeNO
Purtroppo nessuna di queste soluzioni ha fornito davvero risolve il problema perché alla fine le API mancano seriamente quando si tratta di fornire le informazioni pertinenti. Puoi fare alcune ipotesi, tuttavia l'utilizzo currentUserNotificationSettings
(iOS8 +) non è sufficiente nella sua forma attuale per rispondere davvero alla domanda. Anche se molte delle soluzioni qui sembrano suggerire che o quello oisRegisteredForRemoteNotifications
sia più una risposta definitiva, in realtà non lo è.
Considera questo:
con isRegisteredForRemoteNotifications
stati della documentazione:
Restituisce SÌ se l'applicazione è attualmente registrata per le notifiche remote, tenendo conto di tutte le impostazioni di sistema ...
Tuttavia, se si lancia semplicemente un NSLog
delegato nell'app per osservare il comportamento, è chiaro che questo non si comporta nel modo in cui prevediamo che funzionerà. In realtà riguarda direttamente le notifiche remote che sono state attivate per questa app / dispositivo. Una volta attivato per la prima volta, questo ritornerà sempre YES
. Anche la disattivazione nelle impostazioni (notifiche) comporterà comunque questo ritorno YES
perché, a partire da iOS8, un'app può registrarsi per le notifiche remote e persino inviare a un dispositivo senza che l'utente abbia le notifiche abilitate, semplicemente non possono fare avvisi, Badge e suoni senza che l'utente lo accenda. Le notifiche silenziose sono un buon esempio di qualcosa che potresti continuare a fare anche con le notifiche disattivate.
Per quanto currentUserNotificationSettings
indica una delle quattro cose:
Gli avvisi sono attivi I badge sono attivi Il suono è attivo Nessuno è attivo.
Ciò non fornisce assolutamente alcuna indicazione sugli altri fattori o sul pulsante di notifica stesso.
Un utente può infatti disattivare badge, suoni e avvisi, ma può comunque essere mostrato nella schermata di blocco o nel centro notifiche. Questo utente dovrebbe comunque ricevere notifiche push ed essere in grado di vederle sia nella schermata di blocco che nel centro notifiche. Hanno l'attivazione della notifica. MA currentUserNotificationSettings
tornerà: UIUserNotificationTypeNone
in quel caso. Questo non è veramente indicativo delle impostazioni effettive degli utenti.
Alcune ipotesi si possono fare:
isRegisteredForRemoteNotifications
èNO
tal possibile ritenere che questo dispositivo non sia mai stato registrato correttamente per le notifiche remote.application:didRegisterUserNotificationSettings:
viene effettuato un callback contenente le impostazioni di notifica dell'utente in quanto questa è la prima volta che un utente è stato registrato, le impostazioni dovrebbero indicare ciò che l'utente ha selezionato in termini di richiesta di autorizzazione. Se le impostazioni equivalgono a qualcosa di diverso da: UIUserNotificationTypeNone
quindi è stata concessa l'autorizzazione push, altrimenti è stata rifiutata. La ragione di ciò è che dal momento in cui inizi il processo di registrazione remota l'utente ha solo la possibilità di accettare o rifiutare, con le impostazioni iniziali di un'accettazione che sono le impostazioni che hai impostato durante il processo di registrazione.Per completare la risposta, potrebbe funzionare in questo modo ...
UIRemoteNotificationType types = [[UIApplication sharedApplication] enabledRemoteNotificationTypes];
switch (types) {
case UIRemoteNotificationTypeAlert:
case UIRemoteNotificationTypeBadge:
// For enabled code
break;
case UIRemoteNotificationTypeSound:
case UIRemoteNotificationTypeNone:
default:
// For disabled code
break;
}
modifica: questo non è giusto. dal momento che queste sono cose bit-saggio, non funzionerà con un interruttore, quindi ho finito con questo:
UIRemoteNotificationType types = [[UIApplication sharedApplication] enabledRemoteNotificationTypes];
UIRemoteNotificationType typesset = (UIRemoteNotificationTypeAlert | UIRemoteNotificationTypeBadge);
if((types & typesset) == typesset)
{
CeldaSwitch.chkSwitch.on = true;
}
else
{
CeldaSwitch.chkSwitch.on = false;
}
Per iOS7 e precedenti dovresti effettivamente utilizzare enabledRemoteNotificationTypes
e verificare se è uguale (o non uguale a seconda di ciò che desideri) a UIRemoteNotificationTypeNone
.
Tuttavia per iOS 8 è non è sempre sufficiente controllare soltanto con isRegisteredForRemoteNotifications
il maggior numero di stato sopra. Dovresti anche controllare se è application.currentUserNotificationSettings.types
uguale (o non è uguale a seconda di ciò che vuoi) UIUserNotificationTypeNone
!
isRegisteredForRemoteNotifications
potrebbe restituire true anche se currentUserNotificationSettings.types
restituisce UIUserNotificationTypeNone
.
iOS8 + (OBIETTIVO 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");
}
Qui otteniamo UIRemoteNotificationType da UIApplication. Rappresenta lo stato della notifica push di questa app nell'impostazione, quindi puoi controllarne facilmente il tipo
Cerco di supportare iOS 10 e versioni successive utilizzando la soluzione fornita da @Shaheen Ghiassy ma trovo un problema di privazione enabledRemoteNotificationTypes
. Quindi, la soluzione che trovo usando isRegisteredForRemoteNotifications
invece di quella enabledRemoteNotificationTypes
deprecata in iOS 8. Di seguito è la mia soluzione aggiornata che ha funzionato perfettamente per me:
- (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 possiamo chiamare questa funzione facilmente e accedendo al suo Bool
valore e possiamo convertirla nel valore di stringa in questo modo:
NSString *str = [self notificationServicesEnabled] ? @"YES" : @"NO";
Spero che possa aiutare anche gli altri :) Buona programmazione.
Sebbene la risposta di Zac fosse perfettamente corretta fino a iOS 7, è cambiata da quando iOS 8 è arrivato. Perché enabledRemoteNotificationTypes è stato deprecato da iOS 8 in poi. Per iOS 8 e versioni successive, è necessario utilizzare isRegisteredForRemoteNotifications .
Questa soluzione Swifty ha funzionato bene per me ( iOS8 + ),
Metodo :
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)
}
}
}
Utilizzo :
isNotificationEnabled { (isEnabled) in
if isEnabled{
print("Push notification enabled")
}else{
print("Push notification not enabled")
}
}
ri:
questo è corretto
if (types & UIRemoteNotificationTypeAlert)
ma anche seguire è corretto! (come UIRemoteNotificationTypeNone è 0)
if (types == UIRemoteNotificationTypeNone)
vedi quanto segue
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
Ecco come farlo in Xamarin.ios.
public class NotificationUtils
{
public static bool AreNotificationsEnabled ()
{
var settings = UIApplication.SharedApplication.CurrentUserNotificationSettings;
var types = settings.Types;
return types != UIUserNotificationType.None;
}
}
Se si supporta iOS 10+, utilizzare solo il metodo UNUserNotificationCenter.
In Xamarin, la soluzione sopra descritta non funziona per me. Questo è quello che uso invece:
public static bool IsRemoteNotificationsEnabled() {
return UIApplication.SharedApplication.CurrentUserNotificationSettings.Types != UIUserNotificationType.None;
}
Sta ricevendo un aggiornamento live anche dopo aver modificato lo stato delle notifiche in Impostazioni.
Codice copia e incolla semplice e completo creato dalla soluzione di @ ZacBowling ( https://stackoverflow.com/a/1535427/2298002 )
questo porterà anche l'utente alle impostazioni della tua app e consentirà loro di abilitarlo immediatamente
Ho anche aggiunto una soluzione per verificare se i servizi di localizzazione sono abilitati (e portano anche alle impostazioni)
// 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!