在 Apple 应用中接收消息

当安装到设备上后,您的客户端应用便可通过 FCM APNs 接口接收消息。您可以立即开��使用 Notifications Composer 或在应用服务器上构建的消息向细分用户群发送通知。

处理提醒通知

FCM 会通过 APNs 传送定位到 Apple 应用的所有消息。如需详细了解如何通过 UNUserNotificationCenter 接收 APNs 通知,请参阅 Apple 有关处理通知和通知相关操作的文档。

您必须设置 UNUserNotificationCenter delegate 并实现适当的委托方法才能接收来自 FCM 的显示通知 (display notification)。

Swift

extension AppDelegate: UNUserNotificationCenterDelegate {
  // Receive displayed notifications for iOS 10 devices.
  func userNotificationCenter(_ center: UNUserNotificationCenter,
                              willPresent notification: UNNotification) async
    -> UNNotificationPresentationOptions {
    let userInfo = notification.request.content.userInfo

    // With swizzling disabled you must let Messaging know about the message, for Analytics
    // Messaging.messaging().appDidReceiveMessage(userInfo)

    // ...

    // Print full message.
    print(userInfo)

    // Change this to your preferred presentation option
    return [[.alert, .sound]]
  }

  func userNotificationCenter(_ center: UNUserNotificationCenter,
                              didReceive response: UNNotificationResponse) async {
    let userInfo = response.notification.request.content.userInfo

    // ...

    // With swizzling disabled you must let Messaging know about the message, for Analytics
    // Messaging.messaging().appDidReceiveMessage(userInfo)

    // Print full message.
    print(userInfo)
  }
}

Objective-C

// Receive displayed notifications for iOS 10 devices.
// Handle incoming notification messages while app is in the foreground.
- (void)userNotificationCenter:(UNUserNotificationCenter *)center
       willPresentNotification:(UNNotification *)notification
         withCompletionHandler:(void (^)(UNNotificationPresentationOptions))completionHandler {
  NSDictionary *userInfo = notification.request.content.userInfo;

  // With swizzling disabled you must let Messaging know about the message, for Analytics
  // [[FIRMessaging messaging] appDidReceiveMessage:userInfo];

  // ...

  // Print full message.
  NSLog(@"%@", userInfo);

  // Change this to your preferred presentation option
  completionHandler(UNNotificationPresentationOptionBadge | UNNotificationPresentationOptionAlert);
}

// Handle notification messages after display notification is tapped by the user.
- (void)userNotificationCenter:(UNUserNotificationCenter *)center
didReceiveNotificationResponse:(UNNotificationResponse *)response
         withCompletionHandler:(void(^)(void))completionHandler {
  NSDictionary *userInfo = response.notification.request.content.userInfo;
  if (userInfo[kGCMMessageIDKey]) {
    NSLog(@"Message ID: %@", userInfo[kGCMMessageIDKey]);
  }

  // With swizzling disabled you must let Messaging know about the message, for Analytics
  // [[FIRMessaging messaging] appDidReceiveMessage:userInfo];

  // Print full message.
  NSLog(@"%@", userInfo);

  completionHandler();
}

如果您要为通知添加自定义操作,请在通知载荷中设置 click_action 参数。使用的值应与您会在 APNs 载荷的 category 键中使用的值相同。自定义操作必须先注册,然后才能使用。如需了解详情,请参阅 Apple 的本地和远程通知编程指南

如需详细了解发送到您应用的消息,请参阅 FCM 报告信息中心。该信息中心会记录在 Apple 和 Android 设备上发送和打开的消息数量,以及 Android 应用的“展示次数”(用户看到的通知条数)数据。

处理静默推送通知

使用 content-available 键(与 APNs 的 content-available 等效)发送消息时,消息将作为静默通知传送,从而在后台唤醒您的应用以执行后台数据刷新等任务。与前台通知不同,这些通知必须通过 application(_:didReceiveRemoteNotification:fetchCompletionHandler:) 方法处理。

如下所示,实现 application(_:didReceiveRemoteNotification:fetchCompletionHandler:)

Swift

func application(_ application: UIApplication,
                 didReceiveRemoteNotification userInfo: [AnyHashable: Any]) async
  -> UIBackgroundFetchResult {
  // If you are receiving a notification message while your app is in the background,
  // this callback will not be fired till the user taps on the notification launching the application.
  // TODO: Handle data of notification

  // With swizzling disabled you must let Messaging know about the message, for Analytics
  // Messaging.messaging().appDidReceiveMessage(userInfo)

  // Print message ID.
  if let messageID = userInfo[gcmMessageIDKey] {
    print("Message ID: \(messageID)")
  }

  // Print full message.
  print(userInfo)

  return UIBackgroundFetchResult.newData
}

Objective-C

- (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo
    fetchCompletionHandler:(void (^)(UIBackgroundFetchResult))completionHandler {
  // If you are receiving a notification message while your app is in the background,
  // this callback will not be fired till the user taps on the notification launching the application.
  // TODO: Handle data of notification

  // With swizzling disabled you must let Messaging know about the message, for Analytics
  // [[FIRMessaging messaging] appDidReceiveMessage:userInfo];

  // ...

  // Print full message.
  NSLog(@"%@", userInfo);

  completionHandler(UIBackgroundFetchResultNewData);
}

Apple 平台不保证后台通知传递成功。如需了解可能导致后台通知失败的情况,请参阅 Apple 有关将后台更新推送到应用的文档。

解读通知消息载荷

通知消息的载荷是由键和值组成的字典。通过 APNs 发送的通知消息遵循如下 APNs 载荷格式:

  {
    "aps" : {
      "alert" : {
        "body" : "great match!",
        "title" : "Portugal vs. Denmark",
      },
      "badge" : 1,
    },
    "customKey" : "customValue"
  }

在方法调配已停用的情况下处理消息

默认情况下,如果您将应用的委托类分配给 UNUserNotificationCenterMessaging 委托属性,FCM 将对您的应用委托类进行一些调配,自动将 FCM 令牌与该设备的 APNs 令牌相关联,并将收到通知事件传递给 Analytics。如果您明确停用了方法调配、在构建 SwiftUI 应用或为任一委托使用单独的类,则需要手动执行这两个任务。

如需将 FCM 令牌与设备 APNs 令牌相关联,请通过 apnsToken 属性将 APNs 令牌传递给应用委托的令牌刷新处理程序中的 Messaging 类。

Swift

func application(_ application: UIApplication,
    didRegisterForRemoteNotificationsWithDeviceToken deviceToken: Data) {
  Messaging.messaging().apnsToken = deviceToken;
}
 

Objective-C

- (void)application:(UIApplication *)application
    didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken {
  [FIRMessaging messaging].APNSToken = deviceToken;
}

如需向 Analytics 传递通知回执信息,请使用 appDidReceiveMessage(_:) 方法

Swift

func userNotificationCenter(_ center: UNUserNotificationCenter,
                            willPresent notification: UNNotification,
  withCompletionHandler completionHandler: @escaping (UNNotificationPresentationOptions) -> Void) {
  let userInfo = notification.request.content.userInfo

  Messaging.messaging().appDidReceiveMessage(userInfo)

  // Change this to your preferred presentation option
  completionHandler([[.alert, .sound]])
}

func userNotificationCenter(_ center: UNUserNotificationCenter,
                            didReceive response: UNNotificationResponse,
                            withCompletionHandler completionHandler: @escaping () -> Void) {
  let userInfo = response.notification.request.content.userInfo

  Messaging.messaging().appDidReceiveMessage(userInfo)

  completionHandler()
}

func application(_ application: UIApplication,
didReceiveRemoteNotification userInfo: [AnyHashable : Any],
   fetchCompletionHandler completionHandler: @escaping (UIBackgroundFetchResult) -> Void) {
  Messaging.messaging().appDidReceiveMessage(userInfo)
  completionHandler(.noData)
}

Objective-C

- (void)userNotificationCenter:(UNUserNotificationCenter *)center
       willPresentNotification:(UNNotification *)notification
         withCompletionHandler:(void (^)(UNNotificationPresentationOptions))completionHandler {
  NSDictionary *userInfo = notification.request.content.userInfo;

  [[FIRMessaging messaging] appDidReceiveMessage:userInfo];

  // Change this to your preferred presentation option
  completionHandler(UNNotificationPresentationOptionBadge | UNNotificationPresentationOptionAlert);
}

- (void)userNotificationCenter:(UNUserNotificationCenter *)center
didReceiveNotificationResponse:(UNNotificationResponse *)response
         withCompletionHandler:(void(^)(void))completionHandler {
  NSDictionary *userInfo = response.notification.request.content.userInfo;

  [[FIRMessaging messaging] appDidReceiveMessage:userInfo];

  completionHandler();
}

- (void)application:(UIApplication *)application
didReceiveRemoteNotification:(NSDictionary *)userInfo
fetchCompletionHandler:(void (^)(UIBackgroundFetchResult result))completionHandler {
  [[FIRMessaging messaging] appDidReceiveMessage:userInfo];
  completionHandler(UIBackgroundFetchResultNoData);
}