咨询iOS端Firebase Cloud Messaging通知文本的代码修改位置
Hey there! Let's break down where you can modify FCM notification text in your iOS code—there are two main scenarios depending on whether your app is in the foreground or background/not launched:
1. 当App处于前台运行时
When your app is active in the foreground, the system won't automatically display the notification banner. Instead, FCM passes the notification to your UNUserNotificationCenterDelegate implementation, where you can modify the content before choosing to display it.
Use the userNotificationCenter(_:willPresent:withCompletionHandler:) method to tweak the text:
import UserNotifications import FirebaseMessaging class NotificationHandler: NSObject, UNUserNotificationCenterDelegate { func userNotificationCenter(_ center: UNUserNotificationCenter, willPresent notification: UNNotification, withCompletionHandler completionHandler: @escaping (UNNotificationPresentationOptions) -> Void) { // 复制原始通知内容为可修改对象 guard let modifiedContent = notification.request.content.mutableCopy() as? UNMutableNotificationContent else { completionHandler([]) return } // 自定义修改标题、正文或副标题 modifiedContent.title = "自定义标题" modifiedContent.body = "这是修改后的通知正文" modifiedContent.subtitle = "自定义副标题" // 用修改后的内容创建新的通知请求 let updatedRequest = UNNotificationRequest( identifier: notification.request.identifier, content: modifiedContent, trigger: notification.request.trigger ) // 可选:将修改后的通知添加到通知中心,替换原始通知 center.add(updatedRequest) { error in if let error = error { print("更新通知失败: \(error.localizedDescription)") } } // 设置通知展示方式(弹窗、声音、角标等) completionHandler([.banner, .sound]) } }
别忘了在App生命周期早期设置代理(比如在AppDelegate或SceneDelegate中):
UNUserNotificationCenter.current().delegate = NotificationHandler()
2. 当App处于后台或未启动时
这种情况更复杂,因为系统会直接展示通知,不会提前唤醒你的App。你有两种解决方案:
- 方案1:在服务器端修改文本(最简单的方式):发送FCM消息时,直接在payload中设置你想要的
title和body字段。 - 方案2:使用静默通知+本地通知:如果必须在客户端修改,可以发送静默FCM payload(包含
content-available: 1且不含notification字段)唤醒后台的App,然后创建自定义本地通知展示修改后的文本。
以下是方案2的实现步骤:
首先,确保你的App开启了"Remote notifications"后台模式(在Xcode项目的Signing & Capabilities > Background Modes中勾选)。
然后在AppDelegate或SceneDelegate中处理静默通知:
func application(_ application: UIApplication, didReceiveRemoteNotification userInfo: [AnyHashable : Any], fetchCompletionHandler completionHandler: @escaping (UIBackgroundFetchResult) -> Void) { // 从FCM payload的data字段提取原始内容 guard let originalTitle = userInfo["original_title"] as? String, let originalBody = userInfo["original_body"] as? String else { completionHandler(.failed) return } // 修改文本内容 let customTitle = "后台修改: \(originalTitle)" let customBody = "更新后的正文: \(originalBody)" // 构建本地通知内容 let content = UNMutableNotificationContent() content.title = customTitle content.body = customBody content.sound = .default // 立即触发本地通知 let trigger = UNTimeIntervalNotificationTrigger(timeInterval: 0.1, repeats: false) let request = UNNotificationRequest(identifier: UUID().uuidString, content: content, trigger: trigger) // 将本地通知添加到系统通知中心 UNUserNotificationCenter.current().add(request) { error in if let error = error { print("创建本地通知失败: \(error.localizedDescription)") completionHandler(.failed) } else { completionHandler(.newData) } } }
注意:静默通知的FCM payload需要这样设置(不含notification字段,仅保留data和content-available):
{ "to": "DEVICE_TOKEN", "content_available": true, "data": { "original_title": "原始标题", "original_body": "原始正文" } }
关键注意事项
- 务必先向用户请求通知权限,使用
UNUserNotificationCenter.current().requestAuthorization(...)方法。 - 对于iOS 10及以上版本,推荐使用
UNUserNotificationCenterDelegate的方法处理通知,替代旧的UIApplicationDelegate相关方法。
内容的提问来源于stack exchange,提问作者TechKnight25

