tvOS推送通知数据接收:如何传递并解析有效信息?
在tvOS上解析Firebase推送通知的有效信息?
我在tvOS上通过Firebase发送推送通知,使用以下代码接收:
extension AppDelegate: UNUserNotificationCenterDelegate { func userNotificationCenter(_ center: UNUserNotificationCenter, willPresent notification: UNNotification, withCompletionHandler completionHandler: @escaping (UNNotificationPresentationOptions) -> Void) { let content = notification.request.content // API_UNAVAILABLE(tvos) // let userInfo = content.userInfo // let title = content.title // let subtitle = content.subtitle completionHandler([.alert, .sound]) } }
但tvOS下无法像iOS那样直接访问userInfo、title或subtitle属性(这些API在tvOS上标记为API_UNAVAILABLE(tvos))。不过我在Xcode控制台打印UNNotificationContent对象时,能看到标题和消息文本确实存在于对象中,想问下有没有办法在tvOS上传递并解析推送里的有效信息?
可行解决方案
虽然tvOS公开API限制了直接访问这些属性,但可以通过以下两种方式获取推送内容:
1. 运行时反射读取隐藏属性
tvOS的UNNotificationContent底层保留了这些字段,只是对外隐藏。可以通过Objective-C运行时API读取:
import ObjectiveC extension UNNotificationContent { var tvosTitle: String? { return value(forKey: "title") as? String } var tvosBody: String? { return value(forKey: "body") as? String } var tvosUserInfo: [AnyHashable: Any]? { return value(forKey: "userInfo") as? [AnyHashable: Any] } }
在通知回调中直接调用:
func userNotificationCenter(_ center: UNUserNotificationCenter, willPresent notification: UNNotification, withCompletionHandler completionHandler: @escaping (UNNotificationPresentationOptions) -> Void) { let content = notification.request.content let title = content.tvosTitle let body = content.tvosBody let userInfo = content.tvosUserInfo // 处理解析到的内容 completionHandler([.alert, .sound]) }
注意:该方式依赖系统私有API,苹果未来可能修改底层实现,存在审核被拒风险,适合内部测试或非上架场景。
2. 自定义APNs payload字段(推荐)
更安全的方式是在推送时把自定义数据放在aps字典外的自定义字段中,比如构造这样的payload:
{ "aps": { "alert": { "title": "推送标题", "body": "推送内容" }, "sound": "default" }, "custom_data": { "id": "123", "type": "update" } }
接收端通过value(forKey:)读取完整payload字典:
func userNotificationCenter(_ center: UNUserNotificationCenter, willPresent notification: UNNotification, withCompletionHandler completionHandler: @escaping (UNNotificationPresentationOptions) -> Void) { let content = notification.request.content if let payload = content.value(forKey: "_payload") as? [String: Any] { // 提取自定义数据 let customData = payload["custom_data"] as? [String: Any] // 提取标题和内容 let alert = payload["aps"]?["alert"] as? [String: String] let title = alert?["title"] let body = alert?["body"] // 处理数据 } completionHandler([.alert, .sound]) }
这种方式不依赖私有API,稳定性更高,适合上架应用。
3. 利用Firebase Cloud Messaging的data字段
如果使用Firebase发送消息,可直接在data字段传递自定义数据,这些数据会被包含在APNs payload中:
// 发送端示例(Firebase Admin SDK) let message = MessagingMulticastMessage( tokens: ["device_token"], data: [ "custom_id": "456", "message_type": "news" ], apns: APNSPayload( aps: Aps( alert: ApsAlert(title: "新消息", body: "您有一条新通知"), sound: "default" ) ) )
接收端同样通过value(forKey: "_payload")读取完整payload,再提取data字段内容即可。
内容的提问来源于stack exchange,提问作者maxwell
相关产品推荐
相关产品推荐

