Swift ios 检查是否在 ios9 和 ios10 中启用了远程推送通知

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/40531103/
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

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-31 10:45:49  来源:igfitidea点击:

Swift ios check if remote push notifications are enabled in ios9 and ios10

iosswiftxcodepush-notification

提问by user2636197

How can I check if the user has enabled remote notifications on ios 9 or ios 10?

如何检查用户是否在 ios 9 或 ios 10 上启用了远程通知?

If the user has not allowed or clicked No I want to toggle a message asking if they want to enable notifications.

如果用户没有允许或单击否,我想切换一条消息,询问他们是否要启用通知。

采纳答案by Rajat

This answer is outdated and doesn't support on iOS 10, you can check thisanswer.

此答案已过时且不支持 iOS 10,您可以查看答案。



Use this code

使用此代码

let isRegisteredForRemoteNotifications = UIApplication.shared.isRegisteredForRemoteNotifications
if isRegisteredForRemoteNotifications {
     // User is registered for notification
} else {
     // Show alert user is not registered for notification
}

回答by Ogulcan Orhan

Apple recommends to use UserNotificationsframework instead of shared instances. So, do not forget to import UserNotificationsframework. As this framework is new in iOS 10 it's really only safe to use this code in apps building for iOS10+

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
    }
})

You may check official documentation for further information: https://developer.apple.com/documentation/usernotifications

您可以查看官方文档以获取更多信息:https: //developer.apple.com/documentation/usernotifications

回答by tylerSF

I tried Rajat's solution, but it didn't work for me on iOS 10 (Swift 3). It always said that push notifications were enabled. Below is how I solved the problem. This says "not enabled" if the user has tapped "Don't Allow" or if you have not asked the user yet.

我尝试了 Rajat 的解决方案,但它在 iOS 10 (Swift 3) 上对我不起作用。它总是说启用了推送通知。下面是我解决问题的方法。如果用户点击了“不允许”或者您尚未询问用户,则表示“未启用”。

let notificationType = UIApplication.shared.currentUserNotificationSettings!.types
    if notificationType == [] {
        print("notifications are NOT enabled")
    } else {
        print("notifications are enabled")
    }

PS: The method currentUserNotificationSettingswas deprecated in iOS 10.0 but it's still working.

PS:该方法currentUserNotificationSettings在 iOS 10.0 中已被弃用,但它仍然有效。

回答by Imtee

If your app supports iOS 10 and iOS 8, 9 use below code

如果您的应用支持 iOS 10 和 iOS 8、9,请使用以下代码

// At the top, import UserNotifications 
// to use UNUserNotificationCenter
import UserNotifications

Then,

然后,

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")
     }
 }

回答by joel prithivi

in iOS11, Swift 4...

在 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)

                }
            }
        }
    }

回答by onmyway133

@Rajat's answer is not enough.

@Rajat 的回答还不够。

  • isRegisteredForRemoteNotificationsis that your app has connected to APNS and get device token, this can be for silent push notification
  • currentUserNotificationSettingsis for user permissions, without this, there is no alert, banner or sound push notification delivered to the app
  • isRegisteredForRemoteNotifications是您的应用程序已连接到 APNS 并获取设备令牌,这可以用于静默推送通知
  • currentUserNotificationSettings用于用户权限,没有此权限,则不会向应用程序发送警报、横幅或声音推送通知

Here is the check

这是支票

static var isPushNotificationEnabled: Bool {
  guard let settings = UIApplication.shared.currentUserNotificationSettings
    else {
      return false
  }

  return UIApplication.shared.isRegisteredForRemoteNotifications
    && !settings.types.isEmpty
}

For iOS 10, instead of checking for currentUserNotificationSettings, you should use UserNotificationsframework

对于 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")
  }
})

Push notification can be delivered to our apps in many ways, and we can ask for that

推送通知可以通过多种方式发送到我们的应用程序,我们可以要求

UNUserNotificationCenter.current()
  .requestAuthorization(options: [.alert, .sound, .badge])

User can go to Settings app and turn off any of those at any time, so it's best to check for that in the settingsobject

用户可以随时转到“设置”应用程序并关闭其中任何一项,因此最好在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 }
}

回答by Oscar Apeland

Here's a solution for getting a string describing the current permission that works with iOS 9 trough iOS 11, with Swift 4. This implementation uses Whenfor promises.

这是一个用于获取描述当前权限的字符串的解决方案,该字符串在 iOS 11 和 Swift 4 中适用于 iOS 9。此实现使用When作为承诺。

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
}

回答by Joey

Even though user doesn't allow the push notifications, the device token is available. So it would be also a good idea to check if it's allowedto receive the push notifications.

即使用户不允许推送通知,设备令牌也是可用的。因此,检查是否允许接收推送通知也是一个好主意。

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)
        }
    }
}

回答by Debaprio B

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
    }
}

回答by Vishal Shelake

for iOS12 and Swift 4 also support iOS13 and Swift5 I also created a git for this you can check here

对于 iOS12 和 Swift 4 也支持 iOS13 和 Swift5 我还为此创建了一个 git 你可以在这里查看

just add this singleton file in your XCode Project

只需在您的 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)

        }

    }


}

to access this code on ViewController user this on viewDidLoad

在 ViewDidLoad 上访问 ViewController 用户这个代码

NotificaionStatusCheck.shared.currentViewController(self)