19 ответов:
вызов
enabledRemoteNotificationsTypesи проверьте маску.например:
UIRemoteNotificationType types = [[UIApplication sharedApplication] enabledRemoteNotificationTypes]; if (types == UIRemoteNotificationTypeNone) // blah blah blahiOS8 и выше:
[[UIApplication sharedApplication] isRegisteredForRemoteNotifications]
Я не могу комментировать (недостаточно репутации), но вопрос re: quantumpotato:
здесь
typesданоUIRemoteNotificationType types = [[UIApplication sharedApplication] enabledRemoteNotificationTypes];можно использовать
if (types & UIRemoteNotificationTypeAlert)вместо
if (types == UIRemoteNotificationTypeNone)позволит вам проверить, включены ли уведомления (и не беспокойтесь о звуках, значках, центре уведомлений и т. д.). Первая строка кода (
types & UIRemoteNotificationTypeAlert) возвращаетYESесли "стиль оповещения" установлен в "баннеры " или" оповещения", иNOесли "стиль оповещения" является значение "нет", независимо от других параметров.
в последней версии iOS этот метод теперь устарел. Для поддержки iOS 7 и iOS 8 используйте:
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; }
обновленный код для 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() }код для swift3. 0, iOS10
let isRegisteredForRemoteNotifications = UIApplication.shared.isRegisteredForRemoteNotifications if isRegisteredForRemoteNotifications { // User is registered for notification } else { // Show alert user is not registered for notification }от iOS9, swift 2.0 UIRemoteNotificationType является устаревшим, используйте следующий код
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. }просто проверьте, включены ли уведомления толчка
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 }
ниже вы найдете полный пример, который охватывает как iOS8, так и iOS7 (и более низкие версии). Обратите внимание, что до iOS8 вы не можете различать "удаленные уведомления отключены" и " только просмотр в lockscreen включено".
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 наблюдаемая версия для 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() } } }
в попытке поддержать как iOS8, так и ниже, мне не очень повезло с использованием
isRegisteredForRemoteNotificationsкак предложил Кевин. Вместо этого я использовалcurrentUserNotificationSettings, который работал в моем тестировании.+ (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; }
к сожалению, ни одно из этих решений действительно решить проблему, потому что в конце дня API серьезно не хватает, когда дело доходит до предоставления соответствующей информации. Вы можете сделать несколько предположений, однако с помощью
currentUserNotificationSettings(iOS8+) просто недостаточно в его нынешнем виде, чтобы действительно ответить на вопрос. Хотя многие решения здесь, похоже, предполагают, что либо это, либоisRegisteredForRemoteNotificationsэто скорее окончательный ответ, это действительно так не.рассмотрим следующий пример:
С
isRegisteredForRemoteNotificationsдокументация гласит:возвращает да, если приложение в настоящее время зарегистрировано для удаленных уведомлений, принимая во внимание любые общесистемные настройки...
однако если вы бросаете просто
NSLogв вашем делегате приложения, чтобы наблюдать за поведением ясно, что это не ведет себя так, как мы ожидаем, что это будет работать. Это на самом деле относится непосредственно к удаленным уведомлениям будучи активирован для этого приложения / устройства. После активации в первый раз это всегда будет возвращатьYES. Даже отключение их в настройках (уведомления) все равно приведет к этому возвращениюYESэто потому, что, начиная с iOS8, приложение может регистрироваться для удаленных уведомлений и даже отправлять на устройство без пользователя с включенными уведомлениями, они просто не могут делать оповещения, значки и звук без включения пользователя. Тихие уведомления являются хорошим примером того, что вы можете продолжайте делать даже с отключенными уведомлениями.насколько
currentUserNotificationSettingsОн указывает на одну из четырех вещей:оповещения о Значки на Звук на Ни один не включен.
это не дает вам абсолютно никаких указаний на другие факторы или сам переключатель уведомлений.
пользователь может на самом деле отключить значки, звук и оповещения, но по-прежнему показывать на экране блокировки или в Центре уведомлений. Этот пользователь должен по-прежнему получать push уведомления и иметь возможность видеть их обоих на экране блокировки и в Центре уведомлений. У них есть переключатель уведомлений. Но
currentUserNotificationSettingsвернутся:UIUserNotificationTypeNoneв этом случае. Это не совсем указывает на фактические настройки пользователей.несколько догадок можно сделать:
- если
isRegisteredForRemoteNotificationsиNOтогда вы можете предположить, что это устройство никогда не было успешно зарегистрировано для удаленных уведомлений.- после первой регистрации для удаленные уведомления обратный вызов
application:didRegisterUserNotificationSettings:сделано содержащий настройки уведомления Пользователя в это время, так как это первый раз, когда пользователь был зарегистрирован настройки должны укажите, что пользователь выбрал с точки зрения запроса разрешения. Если настройки приравниваются к чему-либо, кроме:UIUserNotificationTypeNoneзатем разрешение push было предоставлено, в противном случае оно было отклонено. Причина этого заключается в том, что с момента начала процесса удаленной регистрации пользователь имеет возможность чтобы принять или отклонить с первоначального параметров принимаются параметры настройки при регистрации.
чтобы завершить ответ, он может работать примерно так...
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: это не правильно. поскольку это бит-мудрый материал, он не будет работать с переключателем, поэтому я закончил использовать это:
UIRemoteNotificationType types = [[UIApplication sharedApplication] enabledRemoteNotificationTypes]; UIRemoteNotificationType typesset = (UIRemoteNotificationTypeAlert | UIRemoteNotificationTypeBadge); if((types & typesset) == typesset) { CeldaSwitch.chkSwitch.on = true; } else { CeldaSwitch.chkSwitch.on = false; }
для iOS7 и прежде чем вы действительно должны использовать
enabledRemoteNotificationTypesи проверить, если он равен (или не равен в зависимости от того, что вы хотите)UIRemoteNotificationTypeNone.однако для iOS8 это не всегда достаточно, чтобы проверить только с
isRegisteredForRemoteNotificationsкак многие государства выше. Вы также должны проверить, еслиapplication.currentUserNotificationSettings.typesравно (или не равно в зависимости от того, что вы хотите)UIUserNotificationTypeNone!
isRegisteredForRemoteNotificationsможет вернуть true, даже еслиcurrentUserNotificationSettings.typesвозвращаетUIUserNotificationTypeNone.
UIRemoteNotificationType types = [[UIApplication sharedApplication] enabledRemoteNotificationTypes]; if (types & UIRemoteNotificationTypeAlert) // blah blah blah { NSLog(@"Notification Enabled"); } else { NSLog(@"Notification not enabled"); }здесь мы получаем UIRemoteNotificationType из UIApplication. Он представляет собой состояние push-уведомления этого приложения в настройках, чем вы можете легко проверить его тип
Я пытаюсь поддерживать iOS 10 и выше, используя решение, предоставляемое @Shaheen Ghiassy, но найти проблему лишения
enabledRemoteNotificationTypes. Итак, решение я нахожу с помощьюisRegisteredForRemoteNotificationsвместоenabledRemoteNotificationTypesкоторый устарел в iOS 8. Ниже мое обновленное решение, которое отлично работает для меня:- (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; }и мы можем легко вызвать эту функцию и получить доступ к ее
Boolзначение и может преобразовать его в строковое значение на это:NSString *str = [self notificationServicesEnabled] ? @"YES" : @"NO";надеюсь, что это поможет другим тоже :) Счастливый кодирование.
iOS8+ (цель 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; } }];
хотя ответ Зака был совершенно правильным до iOS 7,он изменился с момента появления iOS 8. Потому что enabledRemoteNotificationTypes была удалена с iOS 8 и выше. Для iOS 8 и более поздних версий необходимо использовать isRegisteredForRemoteNotifications.
- для iOS 7 и до -- > используйте enabledRemoteNotificationTypes
- для iOS 8 и более поздних версий -- > используйте isRegisteredForRemoteNotifications.
этой тренер решение работало хорошо для меня (iOS8+),
метод:
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) } } }использование:
isNotificationEnabled { (isEnabled) in if isEnabled{ print("Push notification enabled") }else{ print("Push notification not enabled") } }
re:
это правильно
if (types & UIRemoteNotificationTypeAlert)но это правильно ! (поскольку UIRemoteNotificationTypeNone равен 0)
if (types == UIRemoteNotificationTypeNone)см. ниже
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
вот как это сделать в Xamarin.усвн.
public class NotificationUtils { public static bool AreNotificationsEnabled () { var settings = UIApplication.SharedApplication.CurrentUserNotificationSettings; var types = settings.Types; return types != UIUserNotificationType.None; } }Если вы поддерживаете iOS 10+, используйте только метод UNUserNotificationCenter.
в Xamarin, все выше решение не работает для меня. Вот что я использую вместо этого:
public static bool IsRemoteNotificationsEnabled() { return UIApplication.SharedApplication.CurrentUserNotificationSettings.Types != UIUserNotificationType.None; }Это обновление также после того как вы изменили статус уведомлений в настройках.
полное легкое копирование и вставка кода, построенного из решения @ZacBowling (https://stackoverflow.com/a/1535427/2298002)
это также приведет пользователя к настройкам вашего приложения и позволит им немедленно включить
Я также добавил в решение для проверки, включены ли службы определения местоположения (и приводит к настройкам)
// 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!
Comments