Відповіді:
Зателефонуйте enabledRemoteNotificationsTypes
і перевірте маску.
Наприклад:
UIRemoteNotificationType types = [[UIApplication sharedApplication] enabledRemoteNotificationTypes];
if (types == UIRemoteNotificationTypeNone)
// blah blah blah
iOS8 і вище:
[[UIApplication sharedApplication] isRegisteredForRemoteNotifications]
iOS 8
та вище є неправильним, оскільки він перевіряє, чи зареєстрований користувач для віддаленого сповіщення. Відповідно до документації: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];
Випуск квантової картоплі:
Де types
дано
UIRemoteNotificationType types = [[UIApplication sharedApplication] enabledRemoteNotificationTypes];
можна використовувати
if (types & UIRemoteNotificationTypeAlert)
замість
if (types == UIRemoteNotificationTypeNone)
дозволить вам перевіряти лише чи ввімкнено сповіщення (і не хвилюйтеся щодо звуків, значків, центру сповіщень тощо). Перший рядок коду ( types & UIRemoteNotificationTypeAlert
) повернеться, YES
якщо для "Стилю сповіщення" встановлено значення "Банери" або "Попередження", а NO
якщо "Стиль сповіщення" встановлено на "Ніхто", незалежно від інших параметрів.
grantedSettings.types.contains(notificationType)
В останній версії 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;
}
UserNotifications
. На жаль, зараз не маю повної відповіді.
Оновлений код для 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 швидкий 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.
}
просто перевірте, чи активовано Push-сповіщення
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 ви не можете розрізняти "віддалене сповіщення вимкнено" та "лише Перегляд на екрані блокування ".
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");
Швидкий 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()
}
}
}
getNotificationSettings(...)
є асинхронним, тому повернення всередину буде ігноровано
Намагаючись підтримати 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;
}
isEnabled = NO;
у ваших if
випадках він не потрібен, оскільки він був ініціалізований якNO
На жаль, жодне з цих рішень не реально вирішило проблему, оскільки наприкінці дня API не вдається серйозно брати участь у наданні відповідної інформації. Ви можете зробити кілька здогадок, однак, використовуючи currentUserNotificationSettings
(iOS8 +), просто не достатньо в його теперішній формі, щоб дійсно відповісти на питання. Хоча, здається, багато рішень тут говорять про те, що це чи isRegisteredForRemoteNotifications
більше, ніж остаточний відповідь, це насправді не так.
Врахуйте це:
з isRegisteredForRemoteNotifications
документацією зазначено:
Повертає ТАК, якщо програма наразі зареєстрована для віддалених сповіщень з урахуванням будь-яких системних налаштувань ...
Однак якщо ви просто киньте NSLog
делегату програми, щоб спостерігати за поведінкою, зрозуміло, що це не так, як ми очікуємо, що це буде працювати. Це стосується безпосередньо віддалених сповіщень, активованих для цього додатка / пристрою. Після активації вперше це завжди повернеться YES
. Навіть якщо вимкнути їх у налаштуваннях (сповіщеннях), це все одно призведе до цього повернення. YES
Це тому, що, як в iOS8, додаток може реєструватися для віддалених сповіщень і навіть надсилати на пристрій без увімкнення користувачем сповіщень, вони просто не можуть робити сповіщення, Значки та звук без включення користувача. Безшумні сповіщення - хороший приклад того, що ви можете продовжувати робити навіть із вимкнутими сповіщеннями.
Наскільки currentUserNotificationSettings
це вказує на одну з чотирьох речей:
Повідомлення увімкнено Значки ввімкнено Звук увімкнено Ніхто не увімкнено.
Це не дає абсолютно жодних вказівок щодо інших факторів чи самого перемикача сповіщень.
Користувач може насправді вимкнути значки, звук та сповіщення, але все-таки відображати його на блокувальному екрані чи в центрі сповіщень. Цей користувач все одно повинен отримувати push-сповіщення та мати можливість бачити їх як на заблокованому екрані, так і в центрі сповіщень. У них увімкнено перемикач сповіщень. АЛЕ currentUserNotificationSettings
повернеться: UIUserNotificationTypeNone
у такому випадку. Це справді не вказує на фактичні настройки користувачів.
Кілька здогадок можна зробити:
isRegisteredForRemoteNotifications
це NO
тоді, ви можете припустити, що цей пристрій ніколи не був успішно зареєстрований для віддалених сповіщень.application:didRegisterUserNotificationSettings:
, що містить налаштування сповіщень користувача в цей час, оскільки це перший раз, коли користувач був зареєстрований, налаштування повинні вказувати, що обрав користувач з точки зору запиту на дозвіл. Якщо налаштування прирівнюються до чогось іншого, ніж: UIUserNotificationTypeNone
тоді було надано дозвіл на натискання, інакше його було відхилено. Причиною цього є те, що з моменту початку процесу віддаленої реєстрації користувач має лише можливість приймати або відхиляти, при цьому початкові параметри прийняття - це налаштування, які ви встановлюєте під час реєстрації.Для завершення відповіді це могло б спрацювати приблизно так ...
UIRemoteNotificationType types = [[UIApplication sharedApplication] enabledRemoteNotificationTypes];
switch (types) {
case UIRemoteNotificationTypeAlert:
case UIRemoteNotificationTypeBadge:
// For enabled code
break;
case UIRemoteNotificationTypeSound:
case UIRemoteNotificationTypeNone:
default:
// For disabled code
break;
}
редагувати: Це неправильно. оскільки це трохи розумні речі, він не буде працювати з комутатором, тому я закінчив використовувати це:
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
може повернути правду, навіть незважаючи на те, що currentUserNotificationSettings.types
повертається UIUserNotificationTypeNone
.
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;
}
}];
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";
Сподіваюся, це допоможе і іншим :) Щасливе кодування.
Хоча відповідь Зака була абсолютно правильною до iOS 7, вона змінилася з моменту появи iOS 8. Оскільки enableRemoteNotificationTypes було вимкнено з iOS 8 і далі. Для iOS 8 та новіших версій потрібно використовувати isRegisteredForRemoteNotifications .
Це рішення Swifty працювало для мене добре ( 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.ios.
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!