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

use*_*197 49 xcode push-notification ios swift

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

如果用户未允许或单击否我想切换询问是否要启用通知的消息.

Ogu*_*han 103

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
    }
})
Run Code Online (Sandbox Code Playgroud)

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

  • 是的,我个人会选择使用switch语句. (13认同)
  • 令人惊讶的是,苹果公司的员工如何始终做到使某些事情变得如此简单,例如访问两个布尔值成为一堆异步请求。我真的很想知道这样做的原因。 (7认同)
  • 在我看来,这是截至2017年7月的正确答案. (2认同)
  • 为什么不是这个`if``if else`和`if else`? (2认同)

tyl*_*rSF 37

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

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

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

  • 'currentUserNotificationSettings' 被弃用iOS的10.0:使用UserNotifications Framework的 - [UNUserNotificationCenter getNotificationSettingsWithCompletionHandler:]和 - [UNUserNotificationCenter getNotificationCategoriesWithCompletionHandler:] (5认同)
  • Cam,我刚刚在10.2(在手机上)和9.3(在模拟器上)上测试了这个代码,它在两者上都有效.tylerSF,谢谢你的解决方案. (3认同)

Imt*_*tee 29

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

// At the top, import UserNotifications 
// to use UNUserNotificationCenter
import UserNotifications
Run Code Online (Sandbox Code Playgroud)

然后,

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")
     }
 }
Run Code Online (Sandbox Code Playgroud)


Raj*_*jat 27

这个答案已经过时,并且在iOS 10上不支持,您可以查看答案.


使用此代码

let isRegisteredForRemoteNotifications = UIApplication.shared.isRegisteredForRemoteNotifications
if isRegisteredForRemoteNotifications {
     // User is registered for notification
} else {
     // Show alert user is not registered for notification
}
Run Code Online (Sandbox Code Playgroud)

  • 它仅告诉您是否生成了令牌(设备已注册),而不是通知被阻止. (4认同)
  • 这似乎不适用于iOS 10.在模拟器中,我单击"不允许",此代码仍然表示用户已注册远程通知. (2认同)
  • 这不是确定这一点的正确方法。当用户禁用通知时,即使应用程序重新启动,此属性也会继续返回 true。这很奇怪,因为它与声明“此方法返回的值考虑了用户接收远程通知的首选项”的文档背道而驰。您还需要检查用户是否允许通知。 (2认同)

joe*_*ivi 16

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

                }
            }
        }
    }
Run Code Online (Sandbox Code Playgroud)

  • @ChrisO,你必须导入 UserNotifications (2认同)

onm*_*133 8

@ Rajat的答案还不够.

  • isRegisteredForRemoteNotifications 是您的应用已连接到APNS并获取设备令牌,这可以用于静默推送通知
  • currentUserNotificationSettings 用于用户权限,没有这个,没有提供给应用程序的警报,横幅或声音推送通知

这是支票

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

  return UIApplication.shared.isRegisteredForRemoteNotifications
    && !settings.types.isEmpty
}
Run Code Online (Sandbox Code Playgroud)

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

Run Code Online (Sandbox Code Playgroud)

推送通知可以通过多种方式提供给我们的应用程序,我们可以提出要求

UNUserNotificationCenter.current()
  .requestAuthorization(options: [.alert, .sound, .badge])
Run Code Online (Sandbox Code Playgroud)

用户可以随时转到"设置"应用并关闭其中任何一个,因此最好在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 }
}
Run Code Online (Sandbox Code Playgroud)

  • 请注意,从 iOS 10 开始不推荐使用 (2认同)

小智 8

对于 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)
            
        }
        
    }
    
    
}
Run Code Online (Sandbox Code Playgroud)

要在 ViewController 上访问此代码,请在 viewDidLoad 上使用此代码

NotificaionStatusCheck.shared.currentViewController(self)
Run Code Online (Sandbox Code Playgroud)


Osc*_*and 7

这是一个解决方案,用于获取描述当前权限的字符串,该权限适用于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
}
Run Code Online (Sandbox Code Playgroud)


小智 5

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
    }
}
Run Code Online (Sandbox Code Playgroud)

  • 请不要这样做使异步操作出现同步 -&gt; _ = semaphore.wait(timeout: .now() + 5) (3认同)

Joe*_*oey 5

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

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)
        }
    }
}
Run Code Online (Sandbox Code Playgroud)