ios 在 iPhone 上确定用户是否启用了推送通知
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/1535403/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Determine on iPhone if user has enabled push notifications
提问by Kevin
I'm looking for a way to determine if the user has, via settings, enabled or disabled their push notifications for my application.
我正在寻找一种方法来确定用户是否通过设置为我的应用程序启用或禁用了他们的推送通知。
回答by Zac Bowling
Call enabledRemoteNotificationsTypes
and check the mask.
打电话enabledRemoteNotificationsTypes
检查面罩。
For example:
例如:
UIRemoteNotificationType types = [[UIApplication sharedApplication] enabledRemoteNotificationTypes];
if (types == UIRemoteNotificationTypeNone)
// blah blah blah
iOS8 and above:
iOS8及以上:
[[UIApplication sharedApplication] isRegisteredForRemoteNotifications]
回答by Tim Camber
quantumpotato's issue:
量子土豆的问题:
Where types
is given by
哪里types
给出
UIRemoteNotificationType types = [[UIApplication sharedApplication] enabledRemoteNotificationTypes];
one can use
一个可以使用
if (types & UIRemoteNotificationTypeAlert)
instead of
代替
if (types == UIRemoteNotificationTypeNone)
will allow you to check only whether notifications are enabled (and don't worry about sounds, badges, notification center, etc.). The first line of code (types & UIRemoteNotificationTypeAlert
) will return YES
if "Alert Style" is set to "Banners" or "Alerts", and NO
if "Alert Style" is set to "None", irrespective of other settings.
将允许您仅检查通知是否已启用(而不必担心声音、徽章、通知中心等)。如果“警报样式”设置为“横幅”或“警报”,并且“警报样式”设置为“无”,则第一行代码 ( types & UIRemoteNotificationTypeAlert
) 将返回,无论其他设置如何。YES
NO
回答by Kevin Sylvestre
In the latest version of iOS this method is now deprecated. To support both iOS 7 and iOS 8 use:
在最新版本的 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;
}
回答by ViJay Avhad
Updated code for swift4.0 , iOS11
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()
}
Code for swift3.0 , iOS10
swift3.0 , iOS10 的代码
let isRegisteredForRemoteNotifications = UIApplication.shared.isRegisteredForRemoteNotifications
if isRegisteredForRemoteNotifications {
// User is registered for notification
} else {
// Show alert user is not registered for notification
}
From iOS9 , swift 2.0 UIRemoteNotificationType is deprecated, use following code
从 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.
}
simply check whether Push notifications are enabled
只需检查是否启用推送通知
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
}
回答by tilo
Below you'll find a complete example that covers both iOS8 and iOS7 (and lower versions). Please note that prior to iOS8 you can't distinguish between "remote notifications disabled" and "only View in lockscreenenabled".
您将在下面找到一个涵盖 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");
回答by Adam Smaka
Swift 3+
斯威夫特 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 Observable Version for iOS10+:
适用于 iOS10+ 的 RxSwift Observable 版本:
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()
}
}
}
回答by Shaheen Ghiassy
In trying to support both iOS8 and lower, I didn't have much luck using isRegisteredForRemoteNotifications
as Kevin suggested. Instead I used currentUserNotificationSettings
, which worked great in my testing.
在尝试同时支持 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;
}
回答by iYorke
Unfortunately none of these solutions provided reallysolve the problem because at the end of the day the APIs are seriously lacking when it comes to providing the pertinent information. You can make a few guesses however using currentUserNotificationSettings
(iOS8+) just isn't sufficient in its current form to really answer the question. Although a lot of the solutions here seem to suggest that either that or isRegisteredForRemoteNotifications
is more of a definitive answer it really is not.
不幸的是,这些提供的解决方案都没有真正解决问题,因为归根结底,API 在提供相关信息方面严重缺乏。您可以进行一些猜测,但是使用currentUserNotificationSettings
(iOS8+) 仅以其当前形式不足以真正回答问题。尽管这里的许多解决方案似乎都表明这是isRegisteredForRemoteNotifications
一个明确的答案,但实际上并非如此。
Consider this:
考虑一下:
with isRegisteredForRemoteNotifications
documentation states:
与isRegisteredForRemoteNotifications
文档状态:
Returns YES if the application is currently registered for remote notifications, taking into account any systemwide settings...
如果应用程序当前已注册远程通知,则返回 YES,同时考虑任何系统范围的设置...
However if you throw a simply NSLog
into your app delegate to observe the behavior it is clear this does not behave the way we are anticipating it will work. It actually pertains directly to remote notifications having been activated for this app/device. Once activated for the first time this will always return YES
. Even turning them off in settings (notifications) will still result in this returning YES
this is because, as of iOS8, an app may register for remote notifications and even send to a device without the user having notifications enabled, they just may not do Alerts, Badges and Sound without the user turning that on. Silent notifications are a good example of something you may continue to do even with notifications turned off.
但是,如果您简单地将 aNSLog
放入您的应用程序委托以观察行为,很明显这不会像我们预期的那样工作。它实际上直接与为此应用程序/设备激活的远程通知有关。一旦第一次激活,这将始终返回YES
。即使在设置(通知)中关闭它们仍然会导致返回YES
这是因为,从 iOS8 开始,应用程序可能会注册远程通知,甚至在用户未启用通知的情况下发送到设备,他们可能不会发出警报,徽章和声音无需用户打开。静默通知就是一个很好的例子,说明即使关闭通知,您也可以继续做一些事情。
As far as currentUserNotificationSettings
it indicates one of four things:
至于currentUserNotificationSettings
它表明四件事之一:
Alerts are on Badges are on Sound is on None are on.
警报开启 徽章开启 声音开启 无开启。
This gives you absolutely no indication whatsoever about the other factors or the Notification switch itself.
这绝对不会为您提供有关其他因素或通知开关本身的任何指示。
A user may in fact turn off badges, sound and alerts but still have show on lockscreen or in notification center. This user should still be receiving push notifications and be able to see them both on the lock screen and in the notification center. They have the notification switch on. BUT currentUserNotificationSettings
will return: UIUserNotificationTypeNone
in that case. This is not truly indicative of the users actual settings.
用户实际上可能会关闭徽章、声音和警报,但仍会在锁屏或通知中心显示。该用户应该仍能接收推送通知,并且能够在锁定屏幕和通知中心看到它们。他们打开了通知。但是currentUserNotificationSettings
会返回:UIUserNotificationTypeNone
在这种情况下。这并不真正代表用户的实际设置。
A few guesses one can make:
人们可以做出一些猜测:
- if
isRegisteredForRemoteNotifications
isNO
then you can assume that this device has never successfully registered for remote notifications. - after the first time of registering for remote notifications a callback to
application:didRegisterUserNotificationSettings:
is made containing user notification settings at this time since this is the first time a user has been registered the settings shouldindicate what the user selected in terms of the permission request. If the settings equate to anything other than:UIUserNotificationTypeNone
then push permission was granted, otherwise it was declined. The reason for this is that from the moment you begin the remote registration process the user only has the ability to accept or decline, with the initial settings of an acceptance being the settings you setup during the registration process.
- 如果
isRegisteredForRemoteNotifications
是,NO
那么您可以假设该设备从未成功注册远程通知。 - 在第一次注册远程通知后,此时
application:didRegisterUserNotificationSettings:
会进行包含用户通知设置的回调,因为这是用户第一次注册,设置应指示用户根据权限请求选择了什么。如果设置等于以下任何内容:UIUserNotificationTypeNone
则授予推送权限,否则拒绝。这样做的原因是,从您开始远程注册过程的那一刻起,用户只能接受或拒绝,接受的初始设置是您在注册过程中设置的设置。
回答by pojomx
To complete the answer, it could work something like this...
要完成答案,它可以像这样工作......
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: This is not right. since these are bit-wise stuff, it wont work with a switch, so I ended using this:
编辑:这是不对的。因为这些是按位的东西,它不能与开关一起使用,所以我结束了使用这个:
UIRemoteNotificationType types = [[UIApplication sharedApplication] enabledRemoteNotificationTypes];
UIRemoteNotificationType typesset = (UIRemoteNotificationTypeAlert | UIRemoteNotificationTypeBadge);
if((types & typesset) == typesset)
{
CeldaSwitch.chkSwitch.on = true;
}
else
{
CeldaSwitch.chkSwitch.on = false;
}
回答by Peter Verhage
For iOS7 and before you should indeed use enabledRemoteNotificationTypes
and check if it equals (or doesn't equal depending on what you want) to UIRemoteNotificationTypeNone
.
对于 iOS7 和之前,您确实应该使用enabledRemoteNotificationTypes
并检查它是否等于(或不等于,取决于您想要的)到UIRemoteNotificationTypeNone
.
However for iOS8 it is notalways enough to only check with isRegisteredForRemoteNotifications
as many state above. You should also check if application.currentUserNotificationSettings.types
equals (or doesn't equal depending on what you want) UIUserNotificationTypeNone
!
然而,对于 iOS8 ,仅检查上述多个状态并不总是足够的isRegisteredForRemoteNotifications
。您还应该检查是否application.currentUserNotificationSettings.types
等于(或不等于,取决于您想要什么)UIUserNotificationTypeNone
!
isRegisteredForRemoteNotifications
might return true even though currentUserNotificationSettings.types
returns UIUserNotificationTypeNone
.
isRegisteredForRemoteNotifications
即使currentUserNotificationSettings.types
返回UIUserNotificationTypeNone
.