Respostas:
Ligue enabledRemoteNotificationsTypes
e verifique a máscara.
Por exemplo:
UIRemoteNotificationType types = [[UIApplication sharedApplication] enabledRemoteNotificationTypes];
if (types == UIRemoteNotificationTypeNone)
// blah blah blah
iOS8 e superior:
[[UIApplication sharedApplication] isRegisteredForRemoteNotifications]
iOS 8
superiores e superiores está errada porque verifica apenas se o usuário se registrou para notificação remota. De acordo com a documentação: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];
questão de quantumpotato:
Onde types
é dado por
UIRemoteNotificationType types = [[UIApplication sharedApplication] enabledRemoteNotificationTypes];
pode-se usar
if (types & UIRemoteNotificationTypeAlert)
ao invés de
if (types == UIRemoteNotificationTypeNone)
permitirá que você verifique apenas se as notificações estão ativadas (e não se preocupe com sons, selos, central de notificações etc.). A primeira linha do código ( types & UIRemoteNotificationTypeAlert
) retornará YES
se "Estilo de alerta" estiver definido como "Banners" ou "Alertas" e NO
se "Estilo de alerta" estiver definido como "Nenhum", independentemente de outras configurações.
grantedSettings.types.contains(notificationType)
Na versão mais recente do iOS, este método está obsoleto. Para oferecer suporte ao iOS 7 e iOS 8, use:
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
. Infelizmente não tenho uma resposta completa agora.
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
}
No iOS9, o swift 2.0 UIRemoteNotificationType está obsoleto, use o seguinte 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.
}
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 abrange iOS8 e iOS7 (e versões inferiores). Observe que, antes do iOS8, não é possível distinguir entre "notificações remotas desativadas" e "apenas a Visualização no bloqueio de tela ativada".
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 do 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()
}
}
}
getNotificationSettings(...)
é assíncrona para que o interior de retorno será ignorar
Ao tentar oferecer suporte ao iOS8 e inferior, não tive muita sorte usando o isRegisteredForRemoteNotifications
que 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;
}
isEnabled = NO;
em seus if
casos não é necessário, uma vez que foi inicializado comoNO
Infelizmente, nenhuma dessas soluções realmente resolveu o problema, porque no final das contas as APIs estão seriamente ausentes quando se trata de fornecer as informações pertinentes. Você pode fazer algumas suposições, no entanto, o uso do currentUserNotificationSettings
iOS8 + não é suficiente em sua forma atual para realmente responder à pergunta. Embora muitas das soluções aqui pareçam sugerir que isso ouisRegisteredForRemoteNotifications
é é uma resposta definitiva, na verdade não é.
Considere isto:
com os isRegisteredForRemoteNotifications
estados da documentação:
Retorna SIM se o aplicativo estiver registrado no momento para notificações remotas, levando em consideração todas as configurações do sistema ...
No entanto, se você incluir um NSLog
delegado simplesmente no seu aplicativo para observar o comportamento, é claro que isso não se comporta da maneira que esperamos que funcione. Na verdade, ele diz respeito diretamente às notificações remotas ativadas para este aplicativo / dispositivo. Uma vez ativado pela primeira vez, isso sempre retornará YES
. Mesmo desativá-los nas configurações (notificações) ainda resultará nesse retorno YES
, porque, a partir do iOS8, um aplicativo pode se registrar para receber notificações remotas e até mesmo enviar para um dispositivo sem que o usuário tenha as notificações ativadas, elas simplesmente não podem fazer alertas, Emblemas e sons sem o usuário ativá-lo. As notificações silenciosas são um bom exemplo de algo que você pode continuar fazendo, mesmo com as notificações desativadas.
Na medida em currentUserNotificationSettings
que indica uma das quatro coisas:
Os alertas estão ativados Os emblemas estão ativados O som está ativado Nenhum está ativado.
Isso não fornece absolutamente nenhuma indicação sobre os outros fatores ou sobre a própria opção de notificação.
De fato, um usuário pode desativar crachás, sons e alertas, mas ainda assim aparecer na tela de bloqueio ou no centro de notificações. Esse usuário ainda deve estar recebendo notificações por push e pode vê-las na tela de bloqueio e no centro de notificações. Eles estão com a notificação ativada. MAS currentUserNotificationSettings
retornará: UIUserNotificationTypeNone
nesse caso. Isso não é realmente indicativo das configurações reais dos usuários.
Algumas suposições podem ser feitas:
isRegisteredForRemoteNotifications
for NO
, você pode assumir que este dispositivo nunca foi registrado com êxito para notificações remotas.application:didRegisterUserNotificationSettings:
é feito um retorno de chamada contendo configurações de notificação do usuário no momento, já que é a primeira vez que um usuário é registrado, as configurações devem indicar o que o usuário selecionou em termos de solicitação de permissão. Se as configurações equivalerem a algo diferente de: a UIUserNotificationTypeNone
permissão push foi concedida, caso contrário, ela foi recusada. A razão para isso é que, a partir do momento em que você inicia o processo de registro remoto, o usuário só pode aceitar ou recusar, com as configurações iniciais de uma aceitação sendo as que você define durante o processo de registro.Para completar a resposta, poderia funcionar algo como isto ...
UIRemoteNotificationType types = [[UIApplication sharedApplication] enabledRemoteNotificationTypes];
switch (types) {
case UIRemoteNotificationTypeAlert:
case UIRemoteNotificationTypeBadge:
// For enabled code
break;
case UIRemoteNotificationTypeSound:
case UIRemoteNotificationTypeNone:
default:
// For disabled code
break;
}
editar: isso não está certo. como essas são coisas pouco inteligentes, ele não funcionará 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 versões anteriores, você deve realmente usar enabledRemoteNotificationTypes
e verificar se é igual (ou não, dependendo do que você deseja) UIRemoteNotificationTypeNone
.
No entanto, para o iOS8, nem sempre é suficiente verificar apenas com o isRegisteredForRemoteNotifications
estado acima. Você também deve verificar se application.currentUserNotificationSettings.types
é igual (ou não é igual, dependendo do que você quiser) UIUserNotificationTypeNone
!
isRegisteredForRemoteNotifications
pode retornar verdadeiro mesmo que currentUserNotificationSettings.types
retorne UIUserNotificationTypeNone
.
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;
}
}];
UIRemoteNotificationType types = [[UIApplication sharedApplication] enabledRemoteNotificationTypes];
if (types & UIRemoteNotificationTypeAlert)
// blah blah blah
{
NSLog(@"Notification Enabled");
}
else
{
NSLog(@"Notification not enabled");
}
Aqui temos o UIRemoteNotificationType de UIApplication. Ele representa o estado da notificação por push deste aplicativo na configuração, do que você pode verificar seu tipo facilmente
Eu tento dar suporte ao iOS 10 e superior usando a solução fornecida por @Shaheen Ghiassy, mas encontro um problema de privação enabledRemoteNotificationTypes
. Portanto, a solução que eu encontrei usando em isRegisteredForRemoteNotifications
vez de enabledRemoteNotificationTypes
que foi preterida 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 estar acessando seu Bool
valor e podemos convertê-lo no valor da string por este:
NSString *str = [self notificationServicesEnabled] ? @"YES" : @"NO";
Espero que ajude os outros também :) Feliz codificação.
Embora a resposta de Zac estivesse perfeitamente correta até o iOS 7, ela mudou desde que o iOS 8 chegou. Como enabledRemoteNotificationTypes foi descontinuado do iOS 8 em diante. Para o iOS 8 e posterior, você precisa usar isRegisteredForRemoteNotifications .
Esta solução Swifty 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")
}
}
ré:
isto está certo
if (types & UIRemoteNotificationTypeAlert)
mas seguir também está correto! (como UIRemoteNotificationTypeNone é 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 no Xamarin.ios.
public class NotificationUtils
{
public static bool AreNotificationsEnabled ()
{
var settings = UIApplication.SharedApplication.CurrentUserNotificationSettings;
var types = settings.Types;
return types != UIUserNotificationType.None;
}
}
Se você suporta o iOS 10 ou superior, use apenas o método UNUserNotificationCenter.
No Xamarin, todas as soluções acima não funcionam para mim. Isto é o que eu uso em vez disso:
public static bool IsRemoteNotificationsEnabled() {
return UIApplication.SharedApplication.CurrentUserNotificationSettings.Types != UIUserNotificationType.None;
}
Ele também recebe uma atualização ao vivo depois que você altera o status da notificação em Configurações.
Código fácil de copiar e colar, completo, criado a partir da solução da @ ZacBowling ( https://stackoverflow.com/a/1535427/2298002 )
isso também trará o usuário às configurações do seu aplicativo e permitirá que ele ative imediatamente
Também adicionei uma solução para verificar se os serviços de localização estão ativados (e também traz 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!