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

后端 未结 11 1256
悲哀的现实
悲哀的现实 2020-12-01 02:26

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

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

相关标签:
11条回答
  • 2020-12-01 03:00

    @Rajat's answer is not enough.

    • isRegisteredForRemoteNotifications is that your app has connected to APNS and get device token, this can be for silent push notification
    • currentUserNotificationSettings is for user permissions, without this, there is no alert, banner or sound push notification delivered to the app

    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 UserNotifications framework

    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 settings object

    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 }
    }
    
    0 讨论(0)
  • 2020-12-01 03:03

    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 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
    }
    
    0 讨论(0)
  • 2020-12-01 03:04

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


    Use this code

    let isRegisteredForRemoteNotifications = UIApplication.shared.isRegisteredForRemoteNotifications
    if isRegisteredForRemoteNotifications {
         // User is registered for notification
    } else {
         // Show alert user is not registered for notification
    }
    
    0 讨论(0)
  • 2020-12-01 03:06
    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
        }
    }
    
    0 讨论(0)
  • 2020-12-01 03:07

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

    just add this singleton file in your XCode Project

    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

    NotificaionStatusCheck.shared.currentViewController(self)
    
    0 讨论(0)
  • 2020-12-01 03:11

    All answers above are almost correct BUT if you have push notifications enabled and all options disabled (alertSetting, lockScreenSetting etc.), authorizationStatus will be authorized and you won't receive any push notifications.

    The most appropriate way to find out if you user can receive remote notifications is to check all these setting values. You can achieve it using extensions.

    Note: This solution works for iOS 10+. If you support older versions, please read previous answers.

    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()
                }
            }
        }
    }
    
    0 讨论(0)
提交回复
热议问题