ios - 必须在应用启动周期调用 `registerUserNotificationSettings:` 吗?

标签 ios iphone permissions push-notification uikit

docs for registerUserNotificationSettings:状态:

If your app displays alerts, play sounds, or badges its icon, you must call this method during your launch cycle to request permission to alert the user in these ways.

我很失望地读到这篇文章,因为应用程序在需要之前请求发送推送通知的许可似乎很粗鲁。例如,在我正在设计的应用程序中,用户必须在有任何理由发送推送通知之前使用我们的在线服务创建一个帐户。并且可能用户从未注册,只是在本地使用该应用程序,因此永远没有任何理由询问。但是如果我只能在应用程序启动时询问,这意味着用户必须创建一个帐户,退出应用程序,然后在我们可以询问之前再次启动它。看起来很奇怪。

这真的有必要吗?我尝试将对 registerUserNotificationSettings: 的调用放入应用程序更相关的部分,但随后应用程序从未提示是否允许发送推送通知。这只是针对 iOS 推送通知的政策,还是有一些方法可以更灵活地决定何时请求发送推送通知的许可?

最佳答案

-registerForNotifications 的初始调用不必在应用程序启动周期中调用。但是,在第一次调用之后,必须始终在应用程序启动周期中调用它。

这里有两个问题,一个是我的,另一个是我用于推送通知的第三方服务。我的问题是我在返回后关闭了调用 -registerForNotifications 的 View Controller ;我没有意识到它是异步运行的。所以我将 -application:didRegisterUserNotificationSettings 添加到我的应用程序委托(delegate)中。一旦用户响应了 -registerForNotifications 的提示,就会调用此方法,我让它发布通知。在调用 -registerForNotifications 之前,我为该通知设置了一个监听器,并且仅在收到通知后才关闭 View Controller 。有点希望有一个委托(delegate)或一个 block 来指定,但没有。

而且我怀疑没有的原因是因为 iOS 真的希望你在 application:didFinishLaunchingWithOptions: 中调用 -registerForNotifications,所以它是异步回调只是应用程序委托(delegate)中的另一种方法是很自然的。 [删除了关于必须重新启动应用程序才能真正获得推送通知的内容。添加:] 另一个问题是我用于推送通知的第三方服务(仍处于 alpha 阶段)通常不发送推送通知。修复后,他们会在我批准推送通知后立即开始工作,无论提示是在应用程序启动期间还是稍后出现。[/Added]

所以这是完整的模式:

  • 在应用委托(delegate)的 application:didFinishLaunchingWithOptions: 方法中调用 -registerForNotifications 如果已设置用户默认值:

    func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {
        if NSUserDefaults.standardUserDefaults().boolForKey("registedNotificationSettings") {
            self.registerForNotifications()
        }
        return true
    }
    
  • 在应用委托(delegate)的 -application:didRegisterUserNotificationSettings: 方法中,配置远程通知,存储用户默认值,并发布通知:

    func application(application: UIApplication, didRegisterUserNotificationSettings notificationSettings: UIUserNotificationSettings) {
        if notificationSettings.types != .None {
            application.registerForRemoteNotifications()
        }
        let defaults = NSUserDefaults.standardUserDefaults()
        if !defaults.boolForKey( "registedNotificationSettings") {
            defaults.setBool(true, forKey: "registedNotificationSettings")
            defaults.synchronize()
        }
        NSNotificationCenter.defaultCenter().postNotification(
            NSNotification(name: "RegistedNotificationSettings", object: notificationSettings)
        )
    }
    
  • 在我的 View Controller 中,按下按钮时,监听该通知,然后请求发送推送通知的权限:

    @IBAction func okayButtonTapped(sender: AnyObject) {
        NSNotificationCenter.defaultCenter().addObserver(
            self,
            selector: #selector(didRegisterNotificationSettings(_:)),
            name: "RegistedNotificationSettings",
            object: nil
        )
        let appDelegate = UIApplication.sharedApplication().delegate as! AppDelegate
        appDelegate.registerForNotifications()
    }
    
  • 然后我们当然需要通知方法,它会在授予权限时关闭 View Controller ,并在未授予权限时执行其他操作:

    func didRegisterNotificationSettings(notification: NSNotification) {
        let status = notification.object as! UIUserNotificationSettings
        if status.types != .None {
            // Yay!
            self.done()
            return
        }
    
        // Tell them a little more about it.
        NSLog("User declined push notifications")
        self.done()
    }
    

使用此配置,一切正常[删除有关 -registerForNotifications 调用时间的错误信息],并且不会在应用启动时提示用户。

关于ios - 必须在应用启动周期调用 `registerUserNotificationSettings:` 吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38436957/

相关文章:

iphone - UIButton 事件 'Touch Up Inside' 不起作用。 'Touch Down' 工作正常

iphone - 如何在 iPhone 中创建一段时间的提醒,例如 30 分钟后提醒我

permissions - 是否有工具可以告诉我创建 Cloudformation 模板需要哪些权限?

sql-server - 如何更改保管箱文件夹的路径

c# - 重复的 GetAccessRules、FileSystemAccessRule 条目

iphone - 如何在拒绝后重新提交 iOS 应用程序

ios - Facebook 在 Visual Studio 的 Xamarin ios 中以编程方式注销

iOS:如何检测矩形区域是否被遮挡,例如通过键盘?

ios - 使用企业帐户证书签署 ipa 文件

ios - 在 NSUserDefaults 中保存图像?