iOS开发:如何在AppDelegate中获取FCM推送Payload里data字段的数据
没问题,我来帮你梳理下在AppDelegate中获取FCM推送里data字段数据的方法,分不同场景和两种常见处理方式来讲解:
1. 使用传统的AppDelegate回调(兼容iOS 9及以下)
这种是旧版的处理逻辑,针对App不同状态有不同的回调入口:
当App处于前台运行时
系统会触发application(_:didReceiveRemoteNotification:fetchCompletionHandler:)方法,你可以直接从传入的userInfo字典里提取data字段:
Swift示例:
func application(_ application: UIApplication, didReceiveRemoteNotification userInfo: [AnyHashable : Any], fetchCompletionHandler completionHandler: @escaping (UIBackgroundFetchResult) -> Void) { // 提取FCM的data字段 if let dataDict = userInfo["data"] as? [String: Any] { // 获取user_name值 if let userName = dataDict["user_name"] as? String { print("获取到用户名称:\(userName)") // 这里可以做后续逻辑,比如更新UI、跳转页面等 } } // 必须调用completionHandler告知系统处理结果 completionHandler(.newData) }
Objective-C示例:
- (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo fetchCompletionHandler:(void (^)(UIBackgroundFetchResult))completionHandler { // 提取FCM的data字段 NSDictionary *dataDict = userInfo[@"data"]; if (dataDict) { NSString *userName = dataDict[@"user_name"]; if (userName) { NSLog(@"获取到用户名称:%@", userName); // 执行后续处理逻辑 } } completionHandler(UIBackgroundFetchResultNewData); }
当App处于后台/未启动时
如果用户是点击推送通知打开App,需要在application(_:didFinishLaunchingWithOptions:)方法中从launchOptions里获取推送数据:
Swift示例:
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool { // 检查是否是通过点击推送通知启动的App if let remoteNotification = launchOptions?[.remoteNotification] as? [AnyHashable: Any] { if let dataDict = remoteNotification["data"] as? [String: Any] { if let userName = dataDict["user_name"] as? String { print("启动时获取到用户名称:\(userName)") } } } return true }
Objective-C示例:
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { // 检查是否来自推送通知启动 NSDictionary *remoteNotification = launchOptions[UIApplicationLaunchOptionsRemoteNotificationKey]; if (remoteNotification) { NSDictionary *dataDict = remoteNotification[@"data"]; if (dataDict) { NSString *userName = dataDict[@"user_name"]; if (userName) { NSLog(@"启动时获取到用户名称:%@", userName); } } } return YES; }
2. 使用UserNotifications框架(iOS 10+推荐)
从iOS 10开始,苹果推荐用UNUserNotificationCenter统一处理推送,不管App处于前台还是后台,都能通过代理方法一站式处理:
首先要在didFinishLaunchingWithOptions中设置代理并请求推送权限:
Swift示例:
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool { // 请求推送权限 UNUserNotificationCenter.current().requestAuthorization(options: [.alert, .sound, .badge]) { granted, error in // 根据权限状态做对应处理 } // 设置代理 UNUserNotificationCenter.current().delegate = self return true } // 遵循UNUserNotificationCenterDelegate协议 extension AppDelegate: UNUserNotificationCenterDelegate { // App前台时,推送到达会触发这个方法 func userNotificationCenter(_ center: UNUserNotificationCenter, willPresent notification: UNNotification, withCompletionHandler completionHandler: @escaping (UNNotificationPresentationOptions) -> Void) { let userInfo = notification.request.content.userInfo if let dataDict = userInfo["data"] as? [String: Any] { if let userName = dataDict["user_name"] as? String { print("前台收到推送,用户名称:\(userName)") } } // 设置前台显示推送的方式(比如弹窗+声音) completionHandler([.alert, .sound]) } // 用户点击推送通知时触发(不管App之前是后台还是未启动) func userNotificationCenter(_ center: UNUserNotificationCenter, didReceive response: UNNotificationResponse, withCompletionHandler completionHandler: @escaping () -> Void) { let userInfo = response.notification.request.content.userInfo if let dataDict = userInfo["data"] as? [String: Any] { if let userName = dataDict["user_name"] as? String { print("点击推送,用户名称:\(userName)") // 这里可以做跳转页面等操作 } } completionHandler() } }
Objective-C示例:
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { // 请求推送权限 [[UNUserNotificationCenter currentNotificationCenter] requestAuthorizationWithOptions:(UNAuthorizationOptionAlert | UNAuthorizationOptionSound | UNAuthorizationOptionBadge) completionHandler:^(BOOL granted, NSError * _Nullable error) { // 处理权限请求结果 }]; // 设置代理 [[UNUserNotificationCenter currentNotificationCenter] setDelegate:self]; return YES; } // 遵循UNUserNotificationCenterDelegate协议 @interface AppDelegate () <UNUserNotificationCenterDelegate> @end @implementation AppDelegate // 前台收到推送时触发 - (void)userNotificationCenter:(UNUserNotificationCenter *)center willPresentNotification:(UNNotification *)notification withCompletionHandler:(void (^)(UNNotificationPresentationOptions))completionHandler { NSDictionary *userInfo = notification.request.content.userInfo; NSDictionary *dataDict = userInfo[@"data"]; if (dataDict) { NSString *userName = dataDict[@"user_name"]; if (userName) { NSLog(@"前台收到推送,用户名称:%@", userName); } } // 设置前台显示选项 completionHandler(UNNotificationPresentationOptionAlert | UNNotificationPresentationOptionSound); } // 用户点击推送时触发 - (void)userNotificationCenter:(UNUserNotificationCenter *)center didReceiveNotificationResponse:(UNNotificationResponse *)response withCompletionHandler:(void (^)(void))completionHandler { NSDictionary *userInfo = response.notification.request.content.userInfo; NSDictionary *dataDict = userInfo[@"data"]; if (dataDict) { NSString *userName = dataDict[@"user_name"]; if (userName) { NSLog(@"点击推送,用户名称:%@", userName); } } completionHandler(); } @end
需要注意:你的Payload同时包含notification和data字段,这种混合类型的推送在App后台时,data字段会自动附加到通知的userInfo中,所以上面的方法都能正常获取到数据。
内容的提问来源于stack exchange,提问作者Yunusbek Sadullaev
相关产品推荐
相关产品推荐

