当应用程序处于后台(最小化)时,推送通知无法工作 - iOS

6

我是Swift的新手,我正在创建一个聊天应用程序,当应用程序处于前台或最小化时,我需要发送通知。

但是当应用程序被最小化时,我没有收到通知(连接USB时有效)。

  1. 启用远程通知

  2. Xcode中设置后台获取

  3. 启用推送通知

  4. 生产APns证书

通知代码:

class AppDelegate: UIResponder, UIApplicationDelegate {

    var window: UIWindow?
    let gcmMessageIDKey = "gcm.message_id"

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

        FirebaseApp.configure()

        Messaging.messaging().delegate = self
        Messaging.messaging().shouldEstablishDirectChannel = true

        if #available(iOS 10.0, *) {

            UNUserNotificationCenter.current().delegate = self

            let authOptions: UNAuthorizationOptions = [.alert, .sound, .badge]
            UNUserNotificationCenter.current().requestAuthorization(
                options: authOptions,
                completionHandler: {_, _ in })
        } else {
            let settings: UIUserNotificationSettings =
                UIUserNotificationSettings(types: [.alert, .sound, .badge], categories: nil)
            application.registerUserNotificationSettings(settings)
        }

        application.registerForRemoteNotifications()

        NotificationCenter.default.addObserver(self, selector: #selector(tokenRefreshNotification(_:)), name: NSNotification.Name.InstanceIDTokenRefresh, object: nil)

        return true
    }

    func application(_ application: UIApplication, didReceiveRemoteNotification userInfo: [AnyHashable: Any]) {

        Messaging.messaging().appDidReceiveMessage(userInfo)         
    }

    func application(_ application: UIApplication, didReceiveRemoteNotification userInfo: [AnyHashable: Any],
                     fetchCompletionHandler completionHandler: @escaping (UIBackgroundFetchResult) -> Void) {

        Messaging.messaging().appDidReceiveMessage(userInfo)

        let action = userInfo["action"] as! String
        let notification = UILocalNotification()
        notification.fireDate = NSDate() as Date
        notification.alertTitle = "test"
        notification.alertBody = "test"
        notification.alertAction = "Ok"
        UIApplication.shared.applicationIconBadgeNumber =  1
        UIApplication.shared.scheduleLocalNotification(notification)

        completionHandler(UIBackgroundFetchResult.newData)
    }

    func application(_ application: UIApplication, didFailToRegisterForRemoteNotificationsWithError error: Error) {
        print("Unable to register for remote notifications: \(error.localizedDescription)")
    }

    func application(_ application: UIApplication, didRegisterForRemoteNotificationsWithDeviceToken deviceToken: Data) {
        print("APNs token retrieved: \(deviceToken)")

        // With swizzling disabled you must set the APNs token here.
        Messaging.messaging().apnsToken = deviceToken
    }       
}

@available(iOS 10, *)
extension AppDelegate : UNUserNotificationCenterDelegate {

    func userNotificationCenter(_ center: UNUserNotificationCenter,
                                willPresent notification: UNNotification,
                                withCompletionHandler completionHandler: @escaping (UNNotificationPresentationOptions) -> Void) {
        let userInfo = notification.request.content.userInfo

        if let messageID = userInfo[gcmMessageIDKey] {
            print("Message ID: \(messageID)")
        }

        completionHandler([.alert, .sound, .badge])
    }

    func userNotificationCenter(_ center: UNUserNotificationCenter,
                                didReceive response: UNNotificationResponse,
                                withCompletionHandler completionHandler: @escaping () -> Void) {
        let userInfo = response.notification.request.content.userInfo

        if let messageID = userInfo[gcmMessageIDKey] {
            print("Message ID: \(messageID)")
        }

        print(userInfo)

        completionHandler()
    }
    @objc func tokenRefreshNotification(_ notification: Notification) {
            guard let token = InstanceID.instanceID().token() else {
            print("No firebase token, aborting registering device")
            return
        }
        print("No firebase token, aborting registering device")           
    }
}   

extension AppDelegate : MessagingDelegate {
    // [START refresh_token]
    func messaging(_ messaging: Messaging, didReceiveRegistrationToken fcmToken: String) {
        print("Firebase registration token: \(fcmToken)")
        Messaging.messaging().subscribe(toTopic: "/topics/channel_18")           
    }

    func messaging(_ messaging: Messaging, didReceive remoteMessage: MessagingRemoteMessage) {
        print("Received data message: \(remoteMessage.appData)")
    }        
}

FCM负载:

 {
     "to" : "/topics/channel_18",
     "data" : {
      "action" : "NOTIFY",
      "message" : "{"text":"test" }"
     },
     "content_available" : true
    }

我已尝试了高优先级和声音选项,但没有一个有效。

请注意,根据客户要求,我没有使用“notification”键,只在FCM载荷中使用data-message

请有人帮助我在应用程序处于后台且没有USB连接时正常工作通知。


  1. "但是当应用程序最小化时,我没有收到通知(连接USB时可以正常工作),您是什么意思?"
  2. "您是在物理设备上测试还是使用模拟器?"
- mfaani
1
你确定你已经关闭了应用程序吗?也就是说,你双击了主屏幕按钮,然后向上滑动了应用程序吗?此外,你是否看过这里的内容:https://dev59.com/KVgQ5IYBdhLWcg3wvGm4 - mfaani
你能否编辑并删除代码中的注释? - mfaani
除了您的编辑之外,请确保您查看整个链接的问题。此外,我还有两个建议:a)在您的前3个步骤(启用远程通知、在Xcode设置中启用后台获取、启用推送通知)中,只需取消选择,然后再次选择并重试。b)从您的有效负载中删除“content-available”标志,然后再次尝试,并验证是否收到任何类型的通知。如果这样不起作用,那我就想不出其他办法了 :/ - mfaani
作为最后的手段,请尝试使用另一台设备进行测试... - mfaani
显示剩余19条评论
1个回答

2
如果它与非静默通知一起工作,那么它的意思就是:
  • 那么负载设置不正确。根据这个 问题 提供的答案,我会将 content_available 字段的位置改为 notification(由于您不想要标题正文,因此只需不添加标题/正文),或者将其放入负载本身,直到看到它工作为止。
  • 我还会确保在 Xcode 中设置了所有正确的功能(启用远程通知、在 Xcode 设置中启用后台获取、启用推送通知)。如前所述,请取消选中并重新检查它们。
  • 并确保你的应用程序已启用 后台应用程序刷新。这与您的通知不同。显然,也要确保您的通知已启用。:

enter image description here

但是,如果您尝试了所有方法,但在11.3版本上仍然无法正常工作,那么可能是一个错误。有另一个开放式问题提到了与您的问题相同的问题。直接从应用程序中运行应用程序,即不要从Xcode启动,然后使用控制台查看与静默通知相关的日志记录。如果您得到像这样的东西:
default 13:11:47.178186 +0200   dasd    DuetActivitySchedulerDaemon Removing a launch request for application <private> by activity <private>   default com.apple.duetactivityscheduler

那很可能是类似于这个iOS11问题的 bug。但你必须要开一个新的 radar,因为我相信那个 radar 被关闭了,因为它已经被修复了!

通知(应用在后台)在IOS10.2上工作,但在最新的IOS版本上不起作用。 - US-1234
有趣。从我在stackoverflow上的另一个回答中,我链接了iOS 11中类似的错误。但是这个问题已经在11.1版本中得到修复。你说你正在测试11.3版本,所以如果它只在这个版本上不起作用,你可能需要提交一个radar。 - mfaani
我的iOS版本是11.4.1 beta最新版,但仍然存在同样的问题。我已经尝试在iOS版本10.2的手机上运行,它可以正常工作。 - US-1234
你的版本是什么?是11.4.1 beta吗? - mfaani
那么为什么你的问题标记为11.3呢? - mfaani
显示剩余3条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接