iOS7和iOS8:如何检测用户对推送通知的请求是“否”

我正在构build一个针对iOS7和iOS8的应用程序。 我要求用户有权发送推送通知。 但由于某些原因,iOS7和iOS8都不会调用我的application:didFailToRegisterForRemoteNotificationsWithError处理程序,如果在询问推送权限时单击“否”。

我的问题:我怎么知道,在iOS7和iOS8上,当用户已经驳回推送通知的请求 – 我怎么知道他们是否拒绝了请求?

我已经看了一堆StackOverflow的答案,并已经实现了他们的build议,但它没有按照logging工作:

  • iOS7:如果用户批准请求,系统调用我的application:didRegisterForRemoteNotificationsWithDeviceToken: handler。 所以我可以说他们批准了。 但是,如果用户拒绝请求,那么我不会得到一个callbackapplication:didFailToRegisterForRemoteNotificationsWithError 。 这看起来像一个错误,我不能告诉用户拒绝请求。
  • iOS8:如果用户批准或拒绝请求,系统调用我的application:didRegisterUserNotificationSettings处理程序。 我可以查看notificationSettings参数来查看用户是否批准了我的请求,所以很方便。 但是,如果我随后调用isRegisteredForRemoteNotifications() (例如,稍后应用程序变为活动状态), 则始终返回true – 即使用户拒绝了请求 所以我得到一个误报。 这看起来像一个错误,我看到其他人也注意到了这一点 。 更新:如果我随后调用let settings = UIApplication.sharedApplication().currentUserNotificationSettings() ,我可以检查settings.types来查看是否允许警报。 所以对于iOS8来说,它看起来就像我所有的设置。

我正在使用一个NSUserDefaults布尔值来跟踪我是否已经要求用户授予权限。

我正在使用硬件设备进行testing(使用iOS7的iPhone 4S和使用iOS8的iPhone 5),而不是模拟器。

我在每次testing后重置设备 ,以使其再次显示请求警报。

以下是我如何注册推送通知。 if分支在iOS8上执行, else分支在iOS7上执行:

  let application = UIApplication.sharedApplication() if (application.respondsToSelector("registerUserNotificationSettings:")) { let settings = UIUserNotificationSettings(forTypes: .Badge | .Alert | .Sound, categories: nil ) application.registerUserNotificationSettings(settings) } else { application.registerForRemoteNotificationTypes(.Badge | .Alert | .Sound) } 

(在iOS8中, application:didRegisterUserNotificationSettings:被调用时,然后调用application.registerForRemoteNotifications() )。

您的didFailToRegisterForRemoteNotificationsWithError方法未被调用,因为注册没有失败 – 甚至从未尝试过,因为用户拒绝了请求。

在iOS7上,你可以做一些事情:

  1. 假设在调用didRegisterForRemoteNotificationsWithDeviceToken之前,远程通知不可用
  2. 检查UIApplication对象上的enabledRemoteNotificationTypes

我试图find解决这个问题的方法。

显示推送通知权限UIAlert时,会显示在我的应用程序外部。 一旦用户select了“不允许”或“确定”,我的应用程序又变得活跃了。

我有一个视图控制器,在提示用户推送权限之前,我正在呈现。 在这个视图控制器我听UIApplicationDidBecomeActiveNotification ,然后closures我的视图控制器。

这一直工作得很好,而我见过的其他解决scheme根本不适合我。

假设你正在编译iOS8或更新版本,你可以使用下面的委托方法:

 func application(application: UIApplication, didRegisterUserNotificationSettings notificationSettings: UIUserNotificationSettings) { print("Notifications status: \(notificationSettings)") } 

然后在你的didFinishLaunching(或哪里是适合你的需要),你必须调用:

 let app = UIApplication.sharedApplication() let settings = UIUserNotificationSettings(forTypes: [.Alert, .Badge, .Sound], categories: nil) app.registerUserNotificationSettings(settings) app.registerForRemoteNotifications() 

此时,您的用户将收到一条典型的“允许/不允许”提示消息。 无论您的用户select什么,您都可以调用上述方法,从而为您的应用程序提供精细的configuration。 结果会是这样的:

 Notification Status: <UIUserNotificationSettings: 0x7fa261701da0; types: (none);> Notification Status: <UIUserNotificationSettings: 0x7ff032e21dd0; types: (UIUserNotificationTypeAlert UIUserNotificationTypeBadge UIUserNotificationTypeSound);> 

在第一种情况下,您会注意到用户拒绝通知。 第二个是关于允许选项。