【问题标题】:iOS7 and iOS8: how to detect when user said No to a request for push notificationsiOS7 和 iOS8:如何检测用户何时拒绝推送通知请求
【发布时间】:2015-01-25 12:26:37
【问题描述】:

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

我的问题:在 iOS7 和 iOS8 上,我如何知道用户何时拒绝了推送通知的请求 - 我如何知道他们是否拒绝了该请求?

我查看了一堆 StackOverflow 答案并实施了他们的建议,但它并没有像记录的那样工作:

  • iOS7:如果用户批准请求,系统调用我的application:didRegisterForRemoteNotificationsWithDeviceToken: 处理程序。所以我可以说他们批准了它。但如果用户拒绝该请求,那么我不会收到application:didFailToRegisterForRemoteNotificationsWithError 的回调。这似乎是一个错误,我无法判断用户拒绝了该请求。
  • iOS8:如果用户批准或拒绝请求,系统确实调用我的application:didRegisterUserNotificationSettings处理程序。我可以查看notificationSettings 参数来查看用户是否批准或拒绝了我的请求,这样很方便。 但是,如果我随后调用 isRegisteredForRemoteNotifications()(例如,当应用程序稍后激活时),它总是返回 true ——即使用户拒绝了请求。所以我得到一个误报。这似乎是一个错误,我看到 others have noticed this as well 更新:如果我随后调用 let settings = UIApplication.sharedApplication().currentUserNotificationSettings(),我可以检查 settings.types 以查看是否允许警报。所以对于 iOS8,看起来我已经准备好了。

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

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

我是resetting my device after each test,让它再次显示请求警报。

以下是我注册推送通知的方式。 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())。

【问题讨论】:

    标签: ios ios7 swift push-notification apple-push-notifications


    【解决方案1】:

    我试图找到解决同样问题的方法。

    当显示推送通知权限 UIAlert 时,它会从我的应用程序外部显示。一旦用户选择了“不允许”或“确定”,我的应用就会再次激活。

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

    这一直运作良好,而我见过的所有其他解决方案都对我根本不起作用。

    【讨论】:

    • 正如 Paulw11 在他的回答和 cmets 中提到的,您可以在 UIApplication 上查看 isRegisteredForRemoteNotifications 以查看他们是否接受了
    【解决方案2】:

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

    在 iOS7 上你可以做几件事:

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

    【讨论】:

    • 谢谢...换句话说,我无法收到用户拒绝了应用程序的推送请求的通知。我最初计划创建一个入门页面来解释推送通知的好处,底部有一个按钮,上面写着“打开推送通知”。在他们点击它并批准或拒绝后,我将根据他们是批准还是拒绝,将按钮替换为一条消息。
    • 不,您不会收到明确通知他们已拒绝。您只能尝试从缺少他们已批准的通知中推断出来
    • 不确定,但看起来不再有效,“iOS 8.0 及更高版本不支持 enabledRemoteNotificationTypes。”
    • 现在您可以在 UIApplication 对象上查看isRegisteredForRemoteNotifications
    • 这里同样需要使用 Swift 和 iOS8。查看支持的 UIUserNotificationSettings 类型是 .Alert .Sound。 .Badge 和 .None。问题是 .None 将被返回,如果它从未被检查过并且如果用户拒绝。看来我们需要添加自己的逻辑来进一步区分这种情况并做出相应的反应。
    【解决方案3】:

    假设您正在针对 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()
    

    此时,您的用户将收到一条典型的允许/不允许提示消息提示。无论您的用户选择什么,您都会收到对上述方法的调用,从而可以对您的应用程序进行细粒度配置。结果将类似于:

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

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

    【讨论】:

    • 如果用户拒绝,为什么你认为didRegisterUserNotificationSettings 会被调用?
    • 我在 iOS 9 的模拟器和 iPhone 6s 上对此进行了测试。它们都按描述工作。感谢您的回答!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-01-14
    • 2015-04-10
    • 1970-01-01
    • 1970-01-01
    • 2015-03-02
    • 2012-02-20
    相关资源
    最近更新 更多