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]等展示选项。注意这个方法是通知到达时的回调,不是用户点击的回调,不要混淆。
二、判断是否通过点击通知启动应用
分两种场景处理:
- 应用完全未启动时:在
application(_:didFinishLaunchingWithOptions:)里检查launchOptions是否包含UIApplication.LaunchOptionsKey.remoteNotification,如果存在,说明是用户点击通知触发的应用启动,同时可取出通知payload做后续逻辑处理。 - 应用后台挂起时:在
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
相关产品推荐
相关产品推荐

