如何检查用户是否在ios 9或ios 10上启用了远程通知?
如果用户不允许或单击“否”,我想切换一条消息,询问他们是否要启用通知。
Answers:
此答案已过时,并且在iOS 10上不支持,您可以检查此答案。
使用此代码
let isRegisteredForRemoteNotifications = UIApplication.shared.isRegisteredForRemoteNotifications
if isRegisteredForRemoteNotifications {
// User is registered for notification
} else {
// Show alert user is not registered for notification
}
Apple建议使用UserNotifications
框架而不是共享实例。因此,不要忘记导入UserNotifications
框架。由于此框架是iOS 10中的新功能,因此只有在为iOS10 +构建的应用中使用此代码才是真正安全的
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
}
})
您可以查看官方文档以获取更多信息:https : //developer.apple.com/documentation/usernotifications
if
if else
和if else
?
我尝试了Rajat的解决方案,但在iOS 10(Swift 3)上对我不起作用。总是说启用了推送通知。以下是我解决问题的方法。如果用户点击了“不允许”或您尚未询问用户,则显示“未启用”。
let notificationType = UIApplication.shared.currentUserNotificationSettings!.types
if notificationType == [] {
print("notifications are NOT enabled")
} else {
print("notifications are enabled")
}
PS:该方法currentUserNotificationSettings
在iOS 10.0中已弃用,但仍可以使用。
如果您的应用支持iOS 10和iOS 8、9,请使用以下代码
// At the top, import UserNotifications
// to use UNUserNotificationCenter
import UserNotifications
然后,
if #available(iOS 10.0, *) {
let current = UNUserNotificationCenter.current()
current.getNotificationSettings(completionHandler: { settings in
switch settings.authorizationStatus {
case .notDetermined:
// Authorization request has not been made yet
case .denied:
// User has denied authorization.
// You could tell them to change this in Settings
case .authorized:
// User has given authorization.
}
})
} else {
// Fallback on earlier versions
if UIApplication.shared.isRegisteredForRemoteNotifications {
print("APNS-YES")
} else {
print("APNS-NO")
}
}
在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)
}
}
}
}
Use of unresolved identifier 'UNUserNotificationCenter'; did you mean 'NSNotificationCenter'?
@Rajat的答案还不够。
isRegisteredForRemoteNotifications
是您的应用已连接到APNS并获取了设备令牌,这可以用于静默推送通知currentUserNotificationSettings
用于用户权限,没有此权限,则不会将警报,横幅或声音推送通知发送到应用程序这是支票
static var isPushNotificationEnabled: Bool {
guard let settings = UIApplication.shared.currentUserNotificationSettings
else {
return false
}
return UIApplication.shared.isRegisteredForRemoteNotifications
&& !settings.types.isEmpty
}
对于iOS 10,而不是检查currentUserNotificationSettings
,您应该使用UserNotifications
框架
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 9(通过iOS 11和Swift 4)的当前权限。此实现使用When for promises。
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
}
即使用户不允许推送通知,设备令牌仍然可用。因此,检查是否允许接收推送通知也是一个好主意。
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)
}
}
}
class func isRegisteredForRemoteNotifications() -> Bool {
if #available(iOS 10.0, *) {
var isRegistered = false
let semaphore = DispatchSemaphore(value: 0)
let current = UNUserNotificationCenter.current()
current.getNotificationSettings(completionHandler: { settings in
if settings.authorizationStatus != .authorized {
isRegistered = false
} else {
isRegistered = true
}
semaphore.signal()
})
_ = semaphore.wait(timeout: .now() + 5)
return isRegistered
} else {
return UIApplication.shared.isRegisteredForRemoteNotifications
}
}
对于iOS12和Swift 4也支持iOS13和Swift5我也为此创建了一个git,您可以在此处查看
只需在您的XCode项目中添加此单例文件
import Foundation
import UserNotifications
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)
notDetermined
还没有请求许可,那么将用户发送到设置的意义何在?在这种情况下,应该请求许可。
如果您启用了推送通知并且禁用了所有选项(alertSetting,lockScreenSetting等),authorizationStatus
则以上所有答案几乎都是正确的,但是authorized
您将不会收到任何推送通知。
找出用户是否可以接收远程通知的最合适方法是检查所有这些设置值。您可以使用扩展来实现。
注意:此解决方案适用于iOS 10+。如果您支持旧版本,请阅读以前的答案。
extension UNNotificationSettings {
func isAuthorized() -> Bool {
guard authorizationStatus == .authorized else {
return false
}
return alertSetting == .enabled ||
soundSetting == .enabled ||
badgeSetting == .enabled ||
notificationCenterSetting == .enabled ||
lockScreenSetting == .enabled
}
}
extension UNUserNotificationCenter {
func checkPushNotificationStatus(onAuthorized: @escaping () -> Void, onDenied: @escaping () -> Void) {
getNotificationSettings { settings in
DispatchQueue.main.async {
guard settings.isAuthorized() {
onDenied()
return
}
onAuthorized()
}
}
}
}