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/