如何控制何时在 iOS 中提示用户提供推送通知权限

Posted

技术标签:

【中文标题】如何控制何时在 iOS 中提示用户提供推送通知权限【英文标题】:How to control when to prompt user for push notification permissions in iOS 【发布时间】:2015-06-13 09:26:08 【问题描述】:

我使用 Swift 和 Xcode 6 以及 Parse 框架为 iPhone 构建了一个应用程序来处理服务。

在遵循有关如何设置推送通知的 Parse 教程时,说明建议我将推送通知放在 App Delegate 文件中。

这是我添加到 App Delegate 文件中的代码...

@UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate 

    var window: UIWindow?
    var pushNotificationsController: PushNotificationController?


    func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool 

         // Register for Push Notifications
        self.pushNotificationsController = PushNotificationController()

        if application.respondsToSelector("registerUserNotificationSettings:") 
            println("registerUserNotificationSettings.RegisterForRemoteNotificatios")
            let userNotificationTypes: UIUserNotificationType = (.Alert | .Badge | .Sound)
            let settings:UIUserNotificationSettings = UIUserNotificationSettings(forTypes: userNotificationTypes, categories: nil)
            application.registerUserNotificationSettings(settings)
            application.registerForRemoteNotifications()
        

        return true;
    

    func application(application: UIApplication, didRegisterForRemoteNotificationsWithDeviceToken deviceToken: NSData) 
        println("didRegisterForRemoteNotificationsWithDeviceToken")
        let installation = PFInstallation.currentInstallation()
        installation.setDeviceTokenFromData(deviceToken)
        installation.saveInBackground()
    

所以发生的情况是,一旦应用程序第一次启动,就会提示用户授予这些权限。

我想要做的只是在执行特定操作后(即在应用程序功能的演练期间)提示这些权限,因此我可以提供更多背景信息来说明我们为什么希望他们这样做允许推送通知。

是否像在我期望提示用户的相关 ViewController 中复制以下代码一样简单?

// In 'MainViewController.swift' file

func promptUserToRegisterPushNotifications() 
        // Register for Push Notifications
        self.pushNotificationsController = PushNotificationController()

        if application.respondsToSelector("registerUserNotificationSettings:") 
            println("registerUserNotificationSettings.RegisterForRemoteNotificatios")
            let userNotificationTypes: UIUserNotificationType = (.Alert | .Badge | .Sound)
            let settings:UIUserNotificationSettings = UIUserNotificationSettings(forTypes: userNotificationTypes, categories: nil)
            application.registerUserNotificationSettings(settings)
            application.registerForRemoteNotifications()
        


func application(application: UIApplication,    didRegisterForRemoteNotificationsWithDeviceToken deviceToken: NSData) 
        println("didRegisterForRemoteNotificationsWithDeviceToken")
        let installation = PFInstallation.currentInstallation()
        installation.setDeviceTokenFromData(deviceToken)
        installation.saveInBackground()

谢谢!

【问题讨论】:

是的,您可以简单地移动该代码以在适当的时间执行:) 感谢 SomeGuy!我会在我回到我的项目后立即尝试,如果我需要更多帮助,请回来报告。谢谢! 如何获取应用程序:UIApplication到另一个viewController中? 嘿,如果有帮助,您介意接受我的回答吗? :) @denislexic,我所做的是在 viewController 中声明了一个全局变量,例如 let application: UIApplication = UIApplication.sharedApplication()。这似乎对我有用。 :) 【参考方案1】:

答案很简单。如果您希望在其他时间提示用户,例如在按下按钮时,只需将有关请求的代码移动到该函数中(或从其他地方调用 promptUserToRegisterPushNotifications())。

要在 AppDelegate 之外获取 application 变量,只需执行以下操作:

let application = UIApplication.shared

希望有帮助:)

【讨论】:

谢谢莱纳斯。 :) 我现在不在我的电脑前尝试这个,这是我的假设,所以感谢您的澄清。 :) 将尝试并报告反馈!谢谢! 嗨,Linus,信不信由你,我现在才开始实施这个解决方案。所以我按照你的建议做了,并将promptUserToRegisterPushNotifications () 方法移动到另一个视图控制器,但现在我遇到了问题,因为上面的 Denislexic 提出了.. 我如何引用application : UIApplication 将设置保存到我的 MainViewController.swift文件? 没问题 ;) 啊,你为什么不把整个 promptUserToRegisterPushNotifications() 方法放到你的 MainVC 中呢? 我确实这样做了,但在方法中有一个 if application.respondsToSelector("registerUserNotificationSettings:"),我的 MainVC 对 application 一无所知。我不确定是否需要在 MainVC 中声明 application 的实例?如果有,怎么做? 酷,所以我找到了“应用程序”问题的解决方案。我只是在我的 MainViewController 中声明了一个 application 变量,例如 let application: UIApplication = UIApplication.sharedApplication()。这解决了我的问题。 :) 谢谢莱纳斯!【参考方案2】:

这是针对 Swift 2 的。我已将 promptUserToRegisterPushNotifications() 放在 MainViewController.swift 中,但我将 didRegisterForRemoteNotificationsWithDeviceToken 留在了 AppDelegate 中,因为当我将它放在同一个 MainViewController.swift 中时它不起作用。

// In 'MainViewController.swift' file
func promptUserToRegisterPushNotifications() 
    // Register for Push Notifications

    let application: UIApplication = UIApplication.sharedApplication()

    if application.respondsToSelector(#selector(UIApplication.registerUserNotificationSettings(_:))) 
        print("registerUserNotificationSettings.RegisterForRemoteNotificatios")

        let notificationSettings = UIUserNotificationSettings(
            forTypes: [.Badge, .Sound, .Alert], categories: nil)
        application.registerUserNotificationSettings(notificationSettings) // Register for Remote Push Notifications
        application.registerForRemoteNotifications()
    



// In AppDelegate
func application(application: UIApplication, didRegisterForRemoteNotificationsWithDeviceToken deviceToken: NSData) 
    let tokenChars = UnsafePointer<CChar>(deviceToken.bytes)
    var tokenString = ""

    for i in 0..<deviceToken.length 
        tokenString += String(format: "%02.2hhx", arguments: [tokenChars[i]])
    

    NSUserDefaults.standardUserDefaults().setObject(tokenString, forKey: "deviceToken")

    print("Device Token:", tokenString)


【讨论】:

【参考方案3】:

这是我在代码中编写的方法,一旦在启动时调用(didFinishLaunch)就可以正常工作

class func registerNotification() 
    if #available(iOS 10.0, *) 
        // push notifications
        UNUserNotificationCenter.current().requestAuthorization(options: [.sound, .alert, .badge]) 
            (granted, error) in
            if (granted) 
                UIApplication.shared.registerForRemoteNotifications()
            
        

        let center  = UNUserNotificationCenter.current()
        center.delegate = AppManager.appDel()
        center.requestAuthorization(options: [.sound, .alert, .badge])  (granted, error) in
            if error == nil 
                UIApplication.shared.registerForRemoteNotifications()
            
        
     else 
        UIApplication.shared.registerUserNotificationSettings(UIUserNotificationSettings(types: [.badge, .sound, .alert], categories: nil))
        UIApplication.shared.registerForRemoteNotifications()
    

【讨论】:

以上是关于如何控制何时在 iOS 中提示用户提供推送通知权限的主要内容,如果未能解决你的问题,请参考以下文章

iOS 9:如何检测用户何时对推送通知请求说“不允许”? [复制]

了解过去是不是在 iOS 上显示过推送通知权限提示

如何检查用户之前是不是在 iOS 中查看过推送通知权限警报视图?

iOS - 未确定推送通知

推送通知iOS - 提示应用程序检查资源并在适当时提供本地通知

如何提示用户接受 AppDelegate 之外的推送通知?