当应用程序处于后台时,iOS 处理通知和有效负载

Posted

技术标签:

【中文标题】当应用程序处于后台时,iOS 处理通知和有效负载【英文标题】:iOS Handle notifications and payload when app is in Background 【发布时间】:2020-10-24 18:56:39 【问题描述】:

我正在开发一个 Swift ios 14 应用程序,它可以发送和接收来自 Firebase Cloud Messaging 的推送通知。

我从 FCM 发送一条消息,其中包含应用程序必须处理的有效负载,使用有效负载数据更新内部 SQLite 数据库以供以后使用,在视图中显示项目。

当应用程序处于前台时,我在 didReceiveRemoteNotification 方法中收到通知并更新数据库,但是当应用程序处于后台或被终止时,收到通知但没有调用任何方法来处理有效负载并更新数据库.

我已经阅读了很多关于这个问题的主题,但我都没有找到解决方案。

目前我不想使用外部数据库插入数据,稍后再读取外部数据库,但是如果没有其他选项我会更改应用程序(原因是我不想要存储用户应用程序之外的任何信息)。

我的 AppDelegate.swift 如下:

func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool 
        //Firebase Auth + APNs
        FirebaseApp.configure()
        UNUserNotificationCenter.current().delegate = self
        let authOptions: UNAuthorizationOptions = [.alert, .badge, .sound]
        UNUserNotificationCenter.current().requestAuthorization(
            options: authOptions,
            completionHandler: _, _ in )
        application.registerForRemoteNotifications()
        Messaging.messaging().delegate = self
        return true
    

func messaging(_ messaging: Messaging, didReceiveRegistrationToken fcmToken: String) 
    UserDefaults.standard.set(fcmToken, forKey: UserConstants.MESSAGING_TOKEN)
    let dataDict:[String: String] = ["token": fcmToken]
      NotificationCenter.default.post(name: Notification.Name("FCMToken"), object: nil, userInfo: dataDict)


func application(_ application: UIApplication, didReceiveRemoteNotification userInfo: [AnyHashable : Any], fetchCompletionHandler completionHandler: @escaping (UIBackgroundFetchResult) -> Void) 
    if(userInfo["name"] != nil) 
        ContactsService.sharedInstance.addAlert(phoneNumber: userInfo["phone"] as! String, name: userInfo["name"] as! String, isLocalized: Bool(userInfo["isLocalized"] as? String), longitude: (userInfo["longitude"] as! NSString).doubleValue, latitude: (userInfo["latitude"] as! NSString).doubleValue)
    

有人可以帮助我,告诉我是否可以这样做,或者是否有必要将数据存储在外部以便以后检索?

谢谢!

【问题讨论】:

【参考方案1】:

推送通知有两种类型,警报通知和后台通知。警报通知允许您提供可见的警报,这些警报可以通过您的应用程序可以自定义的方式进行交互。后台通知允许您的应用程序在收到推送通知后从后台获取数据。即使应用程序没有运行,也应该使用后台通知来使您的应用程序保持最新状态。同样从 ios 10(及更高版本)开始,您可以使用 didReceive 方法来处理警报通知,而不是使用 didReceiveRemoteNotification 方法。

现在回到您的问题,如果出现警报通知,当应用程序处于前台或用户点击应用程序时会调用 didReceive/didReceiveRemoteNotification 方法。因为,你想更新数据库,你可以使用后台通知而不是警报通知,因为它会自动启动你的应用程序,即使它在后台,也会调用 didReceiveRemoteNotification:fetchCompletionHandler。在发送后台推送通知时,请确保您:

编辑 Info.plist 并选中“启用后台模式”和“远程通知”复选框。 将“content-available”:1 添加到您的推送通知负载中,否则应用在后台时不会被唤醒 通知的 POST 请求应包含值为 background 的 apns-push-type 标头字段和值为 5 的 apns-priority 字段。

更多信息请参考: https://developer.apple.com/documentation/usernotifications/setting_up_a_remote_notification_server/pushing_background_updates_to_your_app

【讨论】:

谢谢你的解释,它更清楚:)

以上是关于当应用程序处于后台时,iOS 处理通知和有效负载的主要内容,如果未能解决你的问题,请参考以下文章

当我的应用程序处于后台或关闭时,当远程推送通知到达时从有效负载中获取数据

当应用程序处于未运行或后台状态时,如何处理推送通知有效负载而不点击它

当应用程序在后台收到通知时如何获取通知有效负载数据

当应用程序处于后台时,Android 2nd 推送通知有效负载数据未在附加中接收

当应用程序处于前台时,FCM 处理 IOS 通知,这是我不想

当应用程序处于后台状态时,FCM多次推送通知无法正常工作