Answers:
呼叫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];
Quantumpotato的问题:
types
由哪里给出
UIRemoteNotificationType types = [[UIApplication sharedApplication] enabledRemoteNotificationTypes];
一个可以使用
if (types & UIRemoteNotificationTypeAlert)
代替
if (types == UIRemoteNotificationTypeNone)
将仅允许您检查通知是否已启用(不必担心声音,徽章,通知中心等)。如果“ Alert Style”设置为“ Banners”或“ Alerts”,并且如果“ Alert Style”设置为“ None”,则与其他设置无关,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开始,不推荐使用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之前,您无法区分“禁用了远程通知”和“仅启用了在锁定屏幕中查看 ”。
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
}
适用于iOS10 +的RxSwift可观察版本:
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
像Kevin所建议的那样运气很好。相反,我使用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
文档状态:
如果当前已为远程通知注册了应用程序,则返回YES,并考虑到系统范围内的任何设置...
但是,如果您将一个简单的对象NSLog
放入应用程序委托中以观察行为,则很明显,这与我们预期的行为不符。实际上,它直接与此应用/设备已激活的远程通知有关。首次激活后,它将始终返回YES
。即使在设置(通知)中将其关闭,这仍然会返回YES
此结果,这是因为自iOS8起,一个应用可能会注册远程通知,甚至在用户未启用通知的情况下发送到设备,他们可能不会执行提醒,徽章和声音,而无需用户打开。无提示通知是即使关闭通知后您仍可以继续执行的操作的一个很好的示例。
据currentUserNotificationSettings
它指示的四件事之一:
警报处于启用状态徽章处于启用状态声音处于启用状态。
这绝对不会给您任何有关其他因素或通知开关本身的指示。
用户实际上可以关闭徽章,声音和警报,但仍在锁屏或通知中心中显示。该用户应该仍在接收推送通知,并且能够在锁定屏幕和通知中心中看到它们。他们打开了通知开关。但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
返回也可能返回true 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");
}
在这里,我们从UIApplication获取UIRemoteNotificationType。它表示该应用在设置中的推送通知状态,因此您可以轻松检查其类型
我尝试使用@Shaheen Ghiassy提供的解决方案来支持iOS 10及更高版本,但发现存在剥夺问题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";
希望它也会对其他人有所帮助:)祝您编程愉快。
尽管Zac的答案在iOS 7之前是完全正确的,但自iOS 8到来以来,答案已经改变。因为从iOS 8开始不推荐使用enabledRemoteNotificationTypes。对于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")
}
}
回覆:
这是对的
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方法。
从@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!