在iPhone上确定用户是否启用了推送通知
我正在寻找一种方法来确定用户是否通过设置启用或禁用了我的应用程序的推送通知。
调用enabledRemoteNotificationsTypes
并检查掩码。
例如:
UIRemoteNotificationType types = [[UIApplication sharedApplication] enabledRemoteNotificationTypes]; if (types == UIRemoteNotificationTypeNone) // blah blah blah
iOS8及以上版本:
[[UIApplication sharedApplication] isRegisteredForRemoteNotifications]
我不能评论(没有足够的声望),但重新:quantumpotato的问题:
types
由哪里给出
UIRemoteNotificationType types = [[UIApplication sharedApplication] enabledRemoteNotificationTypes];
一个可以使用
if (types & UIRemoteNotificationTypeAlert)
代替
if (types == UIRemoteNotificationTypeNone)
将只允许您检查是否启用通知(不要担心声音,徽章,通知中心等)。 如果“Alert Style”设置为“Banners”或“Alerts”,则第一行代码( types & UIRemoteNotificationTypeAlert
)将返回YES
如果“Alert Style”设置为“None”,则不pipe其他设置如何,则返回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; }
更新了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之前,您无法区分“禁用远程通知”和“仅启用locking视图 ”。
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+ iOS 10
if #available(iOS 10.0, *) { UNUserNotificationCenter.current().getNotificationSettings(completionHandler: { (settings: UNNotificationSettings) in return settings.authorizationStatus == .authorized }) } else { return UIApplication.shared.currentUserNotificationSettings?.types.contains(UIUserNotificationType.alert) ?? false }
在试图支持iOS8和更低版本时,我没有像Kevinbuild议的那样使用isRegisteredForRemoteNotifications
运气。 相反,我使用currentUserNotificationSettings
,这在我的testing中效果很好。
+ (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; }
不幸的是,所提供的这些解决scheme都没有真正解决问题,因为在提供相关信息时,API在一天结束时严重缺乏。 可以使用currentUserNotificationSettings
(iOS8 +)进行一些猜测,但目前的forms还不足以真正回答问题。 虽然这里的很多解决scheme似乎表明,无论是或者是isRegisteredForRemoteNotifications
更是一个明确的答案,但它确实不是。
考虑这个:
用isRegisteredForRemoteNotifications
文档指出:
如果应用程序当前注册了远程通知,则返回“是”,并考虑到系统范围的所有设置…
但是,如果你只是将一个简单的NSLog
引入你的应用程序委托来观察行为,那么显然这并不是我们预期它会工作的方式。 它实际上直接涉及为这个应用程序/设备激活的远程通知。 一旦第一次激活,这将始终返回YES
。 即使在设置(通知)中closures它们仍然会导致返回YES
这是因为,从iOS8开始,应用程序可能会注册远程通知,甚至在用户没有启用通知的情况下发送到设备,但他们可能不会执行警报,徽章和声音没有用户打开。 无声通知是您即使closures通知也可以继续执行的一个很好的示例。
至于currentUserNotificationSettings
它指出了四件事情之一:
警报是在徽章是在声音上没有。
这绝对没有任何迹象表明其他因素或通知开关本身。
用户实际上可能closures徽章,声音和提醒,但仍然在锁屏或通知中心显示。 此用户仍应该收到推送通知,并能够在locking屏幕和通知中心中看到它们。 他们有通知开关。 但是在这种情况下, currentUserNotificationSettings
将返回: UIUserNotificationTypeNone
。 这并不是真正指示用户的实际设置。
可以做一些猜测:
- 如果
isRegisteredForRemoteNotifications
是NO
那么您可以假定该设备从未成功注册过远程通知。 - 在第一次注册远程通知之后,callback
application:didRegisterUserNotificationSettings:
在此时包含用户通知设置,因为这是用户第一次注册,设置应该指示用户在权限请求方面select的内容。 如果设置等同于以下任何内容: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; }
UIRemoteNotificationType types = [[UIApplication sharedApplication] enabledRemoteNotificationTypes]; if (types & UIRemoteNotificationTypeAlert) // blah blah blah { NSLog(@"Notification Enabled"); } else { NSLog(@"Notification not enabled"); }
这里我们从UIApplication获得UIRemoteNotificationType。 它代表了设置中这个应用程序的推送通知的状态,比你可以轻松地检查它的types
对于iOS7和之前,你应该确实使用enabledRemoteNotificationTypes
并检查它是否等于(或不等于取决于你想要的)到UIRemoteNotificationTypeNone
。
但是对于iOS8来说,仅仅使用isRegisteredForRemoteNotifications
来检查上面的许多状态并不总是足够的。 你还应该检查application.currentUserNotificationSettings.types
等于(或不等于取决于你想要的) UIUserNotificationTypeNone
!
即使currentUserNotificationSettings.types
返回UIUserNotificationTypeNone
isRegisteredForRemoteNotifications
也可能返回true。
虽然Zac的答案在iOS 7之前是完全正确的,但是自从iOS 8到来之后,它已经发生了变化。 由于enabledRemoteNotificationTypes已从iOS 8开始不推荐使用。 对于iOS 8和更高版本,您需要使用isRegisteredForRemoteNotifications 。
- 对于iOS 7和之前 – >使用enabledRemoteNotificationTypes
- 对于iOS 8和更高版本 – >使用isRegisteredForRemoteNotifications。
我尝试使用@Shaheen Ghiassy提供的解决scheme来支持iOS 10及更高版本,但发现剥夺问题enabledRemoteNotificationTypes
。 所以,我find的解决scheme是使用isRegisteredForRemoteNotifications
而不是在enabledRemoteNotificationTypes
中弃用的enabledRemoteNotificationTypes
。下面是我更新的解决scheme,完美地为我工作:
- (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
值,并且可以通过以下方式将它转换为string值:
NSString *str = [self notificationServicesEnabled] ? @"YES" : @"NO";
希望它也能帮助别人:)快乐的编码。
这个Swifty解决scheme适合我( 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") } }
参考
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; } }];
回覆:
这是对的
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中,以上所有的解决scheme都不适合我。 这是我用来代替:
public static bool IsRemoteNotificationsEnabled() { return UIApplication.SharedApplication.CurrentUserNotificationSettings.Types != UIUserNotificationType.None; }
在“设置”中更改通知状态后,也会进行实时更新。
从@ ZacBowling解决scheme( https://stackoverflow.com/a/1535427/2298002 )构build的完全简单的复制和粘贴代码
这也将使用户到您的应用程序设置,并允许他们立即启用
我还添加了一个解决scheme来检查位置服务是否被启用(并且也带来了设置)
// 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!