Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/swift/18.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Swift ios检查ios9和ios10中是否启用了远程推送通知_Ios_Swift_Xcode_Push Notification - Fatal编程技术网

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

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 9或ios 10上启用了远程通知


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

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