You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Flutter:未绑定Firebase Messaging时如何追踪APNS通知的打开

iOS 未集成Firebase Messaging时,APNS通知打开追踪与启动判断

核心思路

不用FCM的话,直接借助iOS原生的UserNotifications框架处理APNS通知的回调,就能实现通知打开追踪和启动来源判断。


一、追踪通知打开事件

不管应用处于前台、后台还是未启动状态,用户点击通知都会触发统一回调,在回调内埋点即可完成追踪:

  • 用户点击通知的统一入口:实现UNUserNotificationCenterDelegate的userNotificationCenter(_:didReceive:withCompletionHandler:)方法,所有用户点击通知的行为都会走到这里。你可以从通知payload中提取自定义标识(比如你在APNS请求里添加的notification_id),上报到自己的统计服务。
  • 前台通知显示控制:如果需要在前台弹出通知,还要实现userNotificationCenter(_:willPresent:withCompletionHandler:),并在completionHandler里指定[.alert, .sound]等展示选项。注意这个方法是通知到达时的回调,不是用户点击的回调,不要混淆。

二、判断是否通过点击通知启动应用

分两种场景处理:

  1. 应用完全未启动时:在application(_:didFinishLaunchingWithOptions:)里检查launchOptions是否包含UIApplication.LaunchOptionsKey.remoteNotification,如果存在,说明是用户点击通知触发的应用启动,同时可取出通知payload做后续逻辑处理。
  2. 应用后台挂起时:在userNotificationCenter(_:didReceive:withCompletionHandler:)回调里,通过UIApplication.shared.applicationState判断状态,如果是.inactive或.background,说明是点击通知唤醒了后台的应用。

代码示例

1. 注册通知与启动检查(AppDelegate)

import UserNotifications

class AppDelegate: UIResponder, UIApplicationDelegate {
    func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
        // 设置通知代理
        UNUserNotificationCenter.current().delegate = self
        
        // 请求通知权限并注册APNS
        UNUserNotificationCenter.current().requestAuthorization(options: [.alert, .sound, .badge]) { granted, _ in
            if granted {
                application.registerForRemoteNotifications()
            }
        }
        
        // 检查是否通过通知启动应用
        if let notificationPayload = launchOptions?[.remoteNotification] as? [String: Any] {
            trackNotificationOpen(payload: notificationPayload)
            // 处理启动时的通知逻辑,比如跳转对应页面
        }
        
        return true
    }
}

2. 实现通知代理方法

extension AppDelegate: UNUserNotificationCenterDelegate {
    // 前台收到通知时,控制是否展示
    func userNotificationCenter(_ center: UNUserNotificationCenter, willPresent notification: UNNotification, withCompletionHandler completionHandler: @escaping (UNNotificationPresentationOptions) -> Void) {
        // 允许前台显示通知
        completionHandler([.alert, .sound])
    }
    
    // 用户点击通知时触发
    func userNotificationCenter(_ center: UNUserNotificationCenter, didReceive response: UNNotificationResponse, withCompletionHandler completionHandler: @escaping () -> Void) {
        let payload = response.notification.request.content.userInfo
        // 追踪通知打开事件
        trackNotificationOpen(payload: payload)
        
        // 判断是否是点击通知唤醒应用
        let appState = UIApplication.shared.applicationState
        if appState == .background || appState == .inactive {
            // 处理唤醒后的逻辑,比如跳转页面
        }
        
        completionHandler()
    }
    
    // 自定义追踪函数
    private func trackNotificationOpen(payload: [String: Any]) {
        // 从payload中提取自定义标识,比如你在APNS请求里加的notification_id
        if let notificationId = payload["notification_id"] as? String {
            // 上报到你的统计服务,比如:
            // AnalyticsService.track(event: "notification_open", params: ["notification_id": notificationId])
            print("通知 \(notificationId) 被打开")
        }
    }
}

为什么FirebaseMessaging.onMessage无效?

FirebaseMessaging.onMessage是FCM封装的回调,只有当通知通过FCM转发(即你集成了FCM并通过FCM发送通知)时才会触发。你直接用APNS发送通知,没有经过FCM链路,自然不会走这个回调,必须用iOS原生的通知回调来处理。

内容的提问来源于stack exchange,提问作者Random Random

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.23 03:05:11