Apple推送通知(APN)不一致?

Tee*_*etz 5 push-notification apple-push-notifications ios swift swift4

当通过APN使用Apple的推送通知时,我们遇到了一个令人困惑的问题.我们有以下场景(非常标准我猜):

当我们的应用程序(我在这里称之为"MyApp")安装并启动时,我们第一次要求用户通过"MyApp"向他发送推送通知的权限.

在这个例子中,AppDelegate看起来像这样:

import UIKit
import UserNotifications

class AppDelegate: UIResponder, UIApplicationDelegate, UNUserNotificationCenterDelegate {

    var window: UIWindow?

    func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {

        // Register Remote Notifications
        UNUserNotificationCenter.current().delegate = self
        self.registerForPushNotifications()

        return true
    }

    // MARK: - Remote Notifications

    func registerForPushNotifications() {
        UNUserNotificationCenter.current().requestAuthorization(options: [.alert, .sound, .badge]) { (granted, error) in
            guard granted else {
                return
            }
            self.getNotificationSettings()
        }
    }

    func getNotificationSettings() {
        UNUserNotificationCenter.current().getNotificationSettings { (settings) in
            guard settings.authorizationStatus == .authorized else {
                return
            }
            DispatchQueue.main.async {
                UIApplication.shared.registerForRemoteNotifications()
            }
        }
    }

    func application(_ application: UIApplication, didRegisterForRemoteNotificationsWithDeviceToken deviceToken: Data) {
        let tokenParts = deviceToken.map { (data) -> String in
            return String(format: "%02.2hhx", data)
        }
        let token = tokenParts.joined()
        print("ApnToken: \(token)")
    }

    func application(_ application: UIApplication, didFailToRegisterForRemoteNotificationsWithError error: Error) {
        print("did Fail to Register for RemoteNotifications")
    }

    func userNotificationCenter(_ center: UNUserNotificationCenter, willPresent notification: UNNotification, withCompletionHandler completionHandler: @escaping (UNNotificationPresentationOptions) -> Void) {
        print("willPresentNotification!")
        completionHandler([.badge, .sound, .alert])
    }

    func userNotificationCenter(_ center: UNUserNotificationCenter, didReceive response: UNNotificationResponse, withCompletionHandler completionHandler: @escaping () -> Void) {
        print("UserDidResponseToNotification!")
        completionHandler()
    }

    func application(_ application: UIApplication, didReceiveRemoteNotification userInfo: [AnyHashable : Any], fetchCompletionHandler completionHandler: @escaping (UIBackgroundFetchResult) -> Void) {
        print("DidReceiveRemoteNotification!")
        completionHandler(.newData)
    }
}
Run Code Online (Sandbox Code Playgroud)

因此,用户安装并启动应用程序,并询问是否允许"MyApp"发送用户推送通知.如果用户接受推送通知application(_:didRegisterForRemoteNotificationsWithDeviceToken:)被调用,我们将收到的deviceToken提供给我们的API.

现在困扰我的部分:

用户还可以选择稍后通过iPhone设置关闭推送通知,如下所示:设置>"MyApp">通知>允许通知>关闭开关

我们的API现在具有针对APN的deviceToken,但用户通过iPhone-Settings关闭了推送通知.

问题":

用户关闭推送通知后,我们仍然可以向设备发送静默推送通知,"MyApp"可以正确获取数据,没有任何问题.

但在另一种情况下:用户安装并启动"MyApp"并在第一次启动Push Notifications时拒绝从Apple获取deviceToken.我试图从Apple获得一个deviceToken,即使用户拒绝了这样的推送通知警告:(但这不起作用 - 我想Apple如果用户拒绝则不提供我的任何功能)

func registerForPushNotifications() {
        UNUserNotificationCenter.current().requestAuthorization(options: [.alert, .sound, .badge]) { (granted, error) in
            self.getNotificationSettings()
        }
    }

    func getNotificationSettings() {
        UNUserNotificationCenter.current().getNotificationSettings { (settings) in
            DispatchQueue.main.async {
                UIApplication.shared.registerForRemoteNotifications()
            }
        }
    }

    func application(_ application: UIApplication, didRegisterForRemoteNotificationsWithDeviceToken deviceToken: Data) {
        let tokenParts = deviceToken.map { (data) -> String in
            return String(format: "%02.2hhx", data)
        }
        let token = tokenParts.joined()
        print("ApnToken: \(token)")
    }
Run Code Online (Sandbox Code Playgroud)

如果他在第一次启动时接受推送通知,那么用户似乎无所谓.我的意思是,我们不能通过横幅或任何东西向用户显示信息,但我们可以使用APN将数据传输到设备,即使用户稍后关闭此设置也是如此.(但是如果他在应用程序启动时拒绝,我们就无法发送任何内容 - 我们需要一次deviceToken)

我在这里误解了一件事吗?这似乎与我不一致.

我试图澄清我的问题,这样每个人都能理解我的要求.请原谅我的"坏"英语,作为一个非母语人士,在这里提出具体问题并不容易.无论如何,如果您需要进一步的信息,或者您不理解我要求的一个或多个要点,请告诉我,我将提供详细的信息并澄清我的问题.

我不知道这是否重要,但目前我们正在使用APN-Development-Certificate(尚未提供分发证书)

Tai*_*ier 0

好问题,

问题是,如果用户允许您发送推送通知(向您提供他/她的设备令牌),您将能够发送推送。通过通知的推送数据可以在不通知用户的情况下发送(静默通知),您可以在此处阅读更多相关信息: https: //medium.com/@m.imadali10/ios-silent-push-notifications-84009d57794c

这就是为什么即使用户阻止显示通知,您也能够发送推送。该设置仅控制显示外观,但由于他/她为您提供了令牌,您仍然可以向他们发送数据。实际上,用户在授予令牌后无法禁用该令牌。

  • 这就是我在苹果通知框架中似乎不一致的地方 (3认同)