iOS 推送通知设置 - 拒绝权限与从未请求权限

iOS Push Notification Settings - Denied Permission vs Permission Never Requested

是否可以区分

的情况
  1. iOS 用户已明确拒绝用户通知权限,并且
  2. iOS 用户从未收到过权限提示?

我的情况:过去,我会提示用户通知权限,但我自己从未跟踪过请求。后来,我不再尝试注册任何通知设置。现在,我想重新引入用户通知。

在应用程序中发生重大事件后,我的计划是显示某种 UI 来解释选择接收用户通知的好处。但是,如果用户已经拒绝,我更愿意显示一个单独的 UI 可以将他们带入 Settings.app。

目前,我正在使用 -[UIApplication currentUserNotificationSettings] 获取当前设置,但对于上述两种情况,这似乎 returns UIUserNotificationTypeNone

就我个人而言,我还没有找到通过快速查询 iOS SDK 来确定这一点的方法。

然而,当 -[UIApplication application:didRegisterUserNotificationSettings:] 被调用时,我已经能够自己跟踪这个记录。

当 iOS 调用此方法时,您可以确定已提示用户提供用户通知权限并且(重要的是)已接受或拒绝它。

发生这种情况时存储您可以稍后检查此值以确定之前是否显示过提示。

示例代码:

- (void)application:(UIApplication *)application didRegisterUserNotificationSettings:(UIUserNotificationSettings *)notificationSettings {
    [[NSUserDefaults standardUserDefaults] setBool:YES forKey:@"ABHasPromptedForUserNotification"];
    //... your other notification registration handling... 
}

- (BOOL)hasPromptedForUserNotification {
    return [[NSUserDefaults standardUserDefaults] boolForKey:@"ABHasPromptedForUserNotification"];
}

仅供参考:我发现在 -[UIApplication application:didRegisterUserNotificationSettings:] 中将 "ABHasPromptedForUserNotification" 设置为 true 比在调用 -[UIApplication registerForRemoteNotifications] 时更可取,因为在某些情况下可以向用户显示多次提示。如果用户将应用设置为后台或接听电话,就会发生这种情况。在这些情况下,提示将被 iOS 隐藏,并在您下次调用 -[UIApplication registerForRemoteNotifications] 时再次显示。在委托中设置此设置可避免认为用户之前已收到提示,并且在这些边缘情况下不会再次收到提示。

没有.

我相信这是故意的。因为通常的情况是在每次应用程序启动时注册远程通知。这意味着用户每次打开应用程序时都不应该看到权限对话框。 iOS 自动执行此操作。但是,如果您在请求权限之前显示额外的屏幕,Apple 将无法让您知道用户过去是否拒绝过权限,因此您可以显示描述用户如何在每次需要时通过设置启用其权限的屏幕。这将撤消 Apple 为停止激怒用户所做的一切。

在您的情况下,您必须遵循相同的策略。在两种情况下仅显示一种类型的解释性屏幕,并在 NSUserDefaults 中保存用户选择,以了解您是否不能再次显示它。先前拒绝权限的用户将看不到权限对话框。虽然您将对新用户有一个好处(这显然是您正在努力实现的):如果用户取消它,您可能会多次显示解释性屏幕。

如果您支持 iOS 10 及更高版本,UNUserNotifications 框架允许更细化。

let current = UNUserNotificationCenter.current()
current.getNotificationSettings(completionHandler: { (settings) in
    if settings.authorizationStatus == .notDetermined {
        // Not requested
    }

    if settings.authorizationStatus == .denied {
        // User said Don't allow
    }
})

以防有人需要检查旧的 UIUserNotification API 以获得访问权限。下面的代码已经过测试。

- (BOOL)isUserNotificationAllowed {
    UIUserNotificationType types = [[UIApplication sharedApplication] currentUserNotificationSettings].types;
    if(types & UIUserNotificationTypeBadge || types & UIUserNotificationTypeSound || types & UIUserNotificationTypeAlert){
        return YES;
    }
    else {
        return NO;
    }
}

更新 iOS 10.0+。
Apple 提供此功能用于检查用户的推送通知权限状态:

[[UNUserNotificationCenter currentNotificationCenter] getNotificationSettingsWithCompletionHandler:^(UNNotificationSettings * _Nonnull settings) {
switch (settings.authorizationStatus) {
  case UNAuthorizationStatusNotDetermined:
    DDLogDebug(@"Not Determined");
    break;
  case UNAuthorizationStatusDenied:
    DDLogDebug(@"Denied");
    break;
  case UNAuthorizationStatusAuthorized:
    DDLogDebug(@"Authorized");
    break;
  case UNAuthorizationStatusProvisional:
    DDLogDebug(@"Provisional");
    break;
}
}];

查看 Apple Doc 了解更多信息。