Swift ios检查ios9和ios10中是否启用了远程推送通知
如何检查用户是否在ios 9或ios 10上启用了远程通知Swift ios检查ios9和ios10中是否启用了远程推送通知,ios,swift,xcode,push-notification,Ios,Swift,Xcode,Push Notification,如何检查用户是否在ios 9或ios 10上启用了远程通知 如果用户未允许或单击“否”,我想切换一条消息,询问他们是否要启用通知。在iOS 10使用UNUserNotificationCenter后更新了答案 private func checkPushNotificationAllowed(completionHandler: @escaping (Bool) -> Void) { if #available(iOS 10.0, *) { UNUserNotifi
如果用户未允许或单击“否”,我想切换一条消息,询问他们是否要启用通知。在iOS 10使用
UNUserNotificationCenter后更新了答案
private func checkPushNotificationAllowed(completionHandler: @escaping (Bool) -> Void) {
if #available(iOS 10.0, *) {
UNUserNotificationCenter.current().getNotificationSettings { (settings) in
if settings.authorizationStatus == .notDetermined || settings.authorizationStatus == .denied {
completionHandler(false)
}
else {
completionHandler(true)
}
}
}
else {
if let settings = UIApplication.shared.currentUserNotificationSettings {
if settings.types.isEmpty {
completionHandler(false)
}
else {
completionHandler(true)
}
}
else {
completionHandler(false)
}
}
}
首先需要导入用户通知
,然后
let current = UNUserNotificationCenter.current()
current.getNotificationSettings(completionHandler: { permission in
switch permission.authorizationStatus {
case .authorized:
print("User granted permission for notification")
case .denied:
print("User denied notification permission")
case .notDetermined:
print("Notification permission haven't been asked yet")
case .provisional:
// @available(iOS 12.0, *)
print("The application is authorized to post non-interruptive user notifications.")
case .ephemeral:
// @available(iOS 14.0, *)
print("The application is temporarily authorized to post notifications. Only available to app clips.")
@unknown default:
print("Unknow Status")
}
})
此代码将一直工作到iOS 9,对于iOS 10,请使用上述代码段
let isRegisteredForRemoteNotifications = UIApplication.shared.isRegisteredForRemoteNotifications
if isRegisteredForRemoteNotifications {
// User is registered for notification
} else {
// Show alert user is not registered for notification
}
我尝试了Rajat的解决方案,但它在iOS 10(Swift 3)上对我无效。它总是说已启用推送通知。下面是我如何解决这个问题的。如果用户点击了“不允许”或您尚未询问用户,则表示“未启用”
let notificationType = UIApplication.shared.currentUserNotificationSettings!.types
if notificationType == [] {
print("notifications are NOT enabled")
} else {
print("notifications are enabled")
}
PS:IOS10.0中不推荐使用方法currentUserNotificationSettings
,但该方法仍在使用。苹果建议使用UserNotifications
框架,而不是共享实例。因此,不要忘记导入UserNotifications
framework。由于此框架在iOS 10中是新的,因此只有在iOS 10+应用程序构建中使用此代码才是真正安全的
let current = UNUserNotificationCenter.current()
current.getNotificationSettings(completionHandler: { (settings) in
if settings.authorizationStatus == .notDetermined {
// Notification permission has not been asked yet, go for it!
} else if settings.authorizationStatus == .denied {
// Notification permission was previously denied, go to settings & privacy to re-enable
} else if settings.authorizationStatus == .authorized {
// Notification permission was already granted
}
})
您可以查看官方文件以了解更多信息:@Rajat的回答还不够
isRegisteredForRemoteNotifications
是指您的应用程序已连接到APN并获取设备令牌,这可以用于静默推送通知
currentUserNotificationSettings
用于用户权限,如果没有此设置,则不会向应用程序发送警报、横幅或声音推送通知
这是支票
static var isPushNotificationEnabled: Bool {
guard let settings = UIApplication.shared.currentUserNotificationSettings
else {
return false
}
return UIApplication.shared.isRegisteredForRemoteNotifications
&& !settings.types.isEmpty
}
对于iOS 10,您应该使用UserNotifications
框架,而不是检查currentUserNotificationSettings
center.getNotificationSettings(completionHandler: { settings in
switch settings.authorizationStatus {
case .authorized, .provisional:
print("authorized")
case .denied:
print("denied")
case .notDetermined:
print("not determined, ask user for permission now")
}
})
推送通知可以通过多种方式发送到我们的应用程序,我们可以要求这样做
UNUserNotificationCenter.current()
.requestAuthorization(options: [.alert, .sound, .badge])
用户可以随时转到设置应用程序并关闭其中任何一个,因此最好在Settings
对象中进行检查
open class UNNotificationSettings : NSObject, NSCopying, NSSecureCoding {
open var authorizationStatus: UNAuthorizationStatus { get }
open var soundSetting: UNNotificationSetting { get }
open var badgeSetting: UNNotificationSetting { get }
open var alertSetting: UNNotificationSetting { get }
open var notificationCenterSetting: UNNotificationSetting { get }
}
如果您的应用程序支持iOS 10和iOS 8、9,请使用以下代码
// At the top, import UserNotifications
// to use UNUserNotificationCenter
import UserNotifications
那么
在iOS11中,Swift 4
UNUserNotificationCenter.current().getNotificationSettings { (settings) in
if settings.authorizationStatus == .authorized {
// Already authorized
}
else {
// Either denied or notDetermined
UNUserNotificationCenter.current().requestAuthorization(options: [.alert, .sound, .badge]) {
(granted, error) in
// add your own
UNUserNotificationCenter.current().delegate = self
let alertController = UIAlertController(title: "Notification Alert", message: "please enable notifications", preferredStyle: .alert)
let settingsAction = UIAlertAction(title: "Settings", style: .default) { (_) -> Void in
guard let settingsUrl = URL(string: UIApplicationOpenSettingsURLString) else {
return
}
if UIApplication.shared.canOpenURL(settingsUrl) {
UIApplication.shared.open(settingsUrl, completionHandler: { (success) in
})
}
}
let cancelAction = UIAlertAction(title: "Cancel", style: .default, handler: nil)
alertController.addAction(cancelAction)
alertController.addAction(settingsAction)
DispatchQueue.main.async {
self.window?.rootViewController?.present(alertController, animated: true, completion: nil)
}
}
}
}
下面是一个解决方案,用于获取描述当前权限的字符串,该权限可通过iOS 9、iOS 11和Swift 4使用。此实现用于承诺
import UserNotifications
private static func getNotificationPermissionString() -> Promise<String> {
let promise = Promise<String>()
if #available(iOS 10.0, *) {
let notificationCenter = UNUserNotificationCenter.current()
notificationCenter.getNotificationSettings { (settings) in
switch settings.authorizationStatus {
case .notDetermined: promise.resolve("not_determined")
case .denied: promise.resolve("denied")
case .authorized: promise.resolve("authorized")
}
}
} else {
let status = UIApplication.shared.isRegisteredForRemoteNotifications ? "authorized" : "not_determined"
promise.resolve(status)
}
return promise
}
导入用户通知
私有静态函数getNotificationPermissionString()->Promise{
让承诺
如果可用(iOS 10.0,*){
let notificationCenter=unuservificationcenter.current()
notificationCenter.getNotificationSettings{(设置)位于
开关设置.授权状态{
案例.未确定:承诺.解决(“未确定”)
案例.拒绝:承诺.解决(“拒绝”)
案例.授权:承诺.解决(“授权”)
}
}
}否则{
let status=UIApplication.shared.isRegisteredForRemoteNotifications?“已授权”:“未确定”
承诺。解决(状态)
}
回报承诺
}
即使用户不允许推送通知,设备令牌仍然可用。因此,检查是否允许它接收推送通知也是一个好主意
private func checkPushNotificationAllowed(completionHandler: @escaping (Bool) -> Void) {
if #available(iOS 10.0, *) {
UNUserNotificationCenter.current().getNotificationSettings { (settings) in
if settings.authorizationStatus == .notDetermined || settings.authorizationStatus == .denied {
completionHandler(false)
}
else {
completionHandler(true)
}
}
}
else {
if let settings = UIApplication.shared.currentUserNotificationSettings {
if settings.types.isEmpty {
completionHandler(false)
}
else {
completionHandler(true)
}
}
else {
completionHandler(false)
}
}
}
以上所有答案几乎都是正确的,但是如果您启用了推送通知,并且禁用了所有选项(alertSetting、lockScreenSetting等),授权状态
将为授权
,您将不会收到任何推送通知
private func checkPushNotificationAllowed(completionHandler: @escaping (Bool) -> Void) {
if #available(iOS 10.0, *) {
UNUserNotificationCenter.current().getNotificationSettings { (settings) in
if settings.authorizationStatus == .notDetermined || settings.authorizationStatus == .denied {
completionHandler(false)
}
else {
completionHandler(true)
}
}
}
else {
if let settings = UIApplication.shared.currentUserNotificationSettings {
if settings.types.isEmpty {
completionHandler(false)
}
else {
completionHandler(true)
}
}
else {
completionHandler(false)
}
}
}
确定用户是否可以接收远程通知的最合适方法是检查所有这些设置值。您可以使用扩展来实现它
注意:此解决方案适用于iOS 10+。如果您支持旧版本,请阅读以前的答案
extension UNNotificationSettings {
func isAuthorized() -> Bool {
guard authorizationStatus == .authorized else {
return false
}
return alertSetting == .enabled ||
soundSetting == .enabled ||
badgeSetting == .enabled ||
notificationCenterSetting == .enabled ||
lockScreenSetting == .enabled
}
}
对于iOS12和Swift 4,还支持iOS13和Swift5
我还为此创建了一个git,您可以查看
只需将此单例文件添加到您的XCode项目中
import Foundation
import UserNotifications
import UIKit
class NotificaionStatusCheck {
var window: UIWindow?
private var currentViewController : UIViewController? = nil
static let shared = NotificaionStatusCheck()
public func currentViewController(_ vc: UIViewController?) {
self.currentViewController = vc
checkNotificationsAuthorizationStatus()
}
private func checkNotificationsAuthorizationStatus() {
let userNotificationCenter = UNUserNotificationCenter.current()
userNotificationCenter.getNotificationSettings { (notificationSettings) in
switch notificationSettings.authorizationStatus {
case .authorized:
print("The app is authorized to schedule or receive notifications.")
case .denied:
print("The app isn't authorized to schedule or receive notifications.")
self.NotificationPopup()
case .notDetermined:
print("The user hasn't yet made a choice about whether the app is allowed to schedule notifications.")
self.NotificationPopup()
case .provisional:
print("The application is provisionally authorized to post noninterruptive user notifications.")
self.NotificationPopup()
}
}
}
private func NotificationPopup(){
let alertController = UIAlertController(title: "Notification Alert", message: "Please Turn on the Notification to get update every time the Show Starts", preferredStyle: .alert)
let settingsAction = UIAlertAction(title: "Settings", style: .default) { (_) -> Void in
guard let settingsUrl = URL(string: UIApplication.openSettingsURLString) else {
return
}
if UIApplication.shared.canOpenURL(settingsUrl) {
UIApplication.shared.open(settingsUrl, completionHandler: { (success) in
})
}
}
let cancelAction = UIAlertAction(title: "Cancel", style: .default, handler: nil)
alertController.addAction(cancelAction)
alertController.addAction(settingsAction)
DispatchQueue.main.async {
self.currentViewController?.present(alertController, animated: true, completion: nil)
}
}
}
要在ViewController上访问此代码,请在viewDidLoad上使用此用户
NotificaionStatusCheck.shared.currentViewController(self)
这似乎不适用于iOS 10。在模拟器中,我点击了“不允许”,这段代码仍然显示用户已注册远程通知。在iOS 10上对我有效。尝试使用实际设备而不是模拟器。它仅会告诉您是否生成了令牌(设备已注册),而不会告诉您通知是否被阻止。iOS模拟器不支持远程通知。只有本地通知这不是确定这一点的正确方法。当用户禁用通知时,即使应用程序重新启动,此属性也会继续返回true。这很奇怪,因为它违背了文档中的说明,“此方法返回的值考虑了用户接收远程通知的首选项。”您需要检查用户是否也允许通知。这是否适用于iOS 9、8、7等…还是需要单独的代码?我不确定,我只在iOS 10.Cam上进行了检查,我刚刚在10.2(在手机上)和9.3(在模拟器上)上测试了这段代码,并且在这两个版本上都有效。tylerSF,感谢您提供的解决方案。此解决方案更好,因为它还管理了用户进入设置、启用/禁用通知和返回应用程序的情况。iOS 10.0中不推荐使用“currentUserNotificationSettings”:使用UserNotifications框架的-[UNUserNotificationCenter getNotificationSettingsWithCompletionHandler:]和-[UnuseNotificationCenter getNotificationCategoriesWithCompletionHandler:]在我看来,这是截至2017年7月的正确答案。为什么这不是if
if else
和if else
?@OgulcanOrhan是的,我知道它是有效的-我使用了你的代码并对你的答案进行了投票,你知道:)-我只是想知道为什么需要调用这三个条件句?我有点迂腐,我想是的,我是一个人ally会选择使用一个switch语句。令人惊讶的是,苹果公司的员工们总是能做出如此简单的事情,比如访问两个布尔值,变成一团乱麻
NotificaionStatusCheck.shared.currentViewController(self)