iOS Push Notification 在锁屏通知中心显示之前如何拦截?

How can I intercept an iOS Push Notification before it's displayed on the lock screen notification center?

我正在努力将一个应用程序与 GCM 集成,以获得简单的全球主题推送通知。与 GCM 通信的服务器端是用 Java/Spring 编写的,并且大部分都按预期工作。但是,我遇到了一些在 iOS 方面可能无法实现的问题。

理想情况下,我希望通过 JSON 结构(字符串格式)发送带有一些元数据的 JSON 结构(字符串格式),就像在显示通知,我打算将其保留在应用程序的其他位置以供查看。

现在,当应用程序处于活动状态时,我没有问题,因为我的应用程序委托正在运行

- (void)application:(UIApplication *)application
    didReceiveRemoteNotification:(NSDictionary *)userInfo 
    fetchCompletionHandler:(void (^)(UIBackgroundFetchResult))handler {
    ....
}

在我的主 viewController 中有一个通知注册,愉快地将远程通知传递到我的 viewController 代码,在那里我可以解析 JSON 并按我喜欢的方式处理它.

但是,我似乎找不到类似的 method/procedure 我可以定义它让我对当应用程序未在前台运行时收到的通知具有相同的控制权。这导致锁定屏幕推送通知以字符串格式显示我的 JSON 结构,显然不是我想要的。

现在,从技术上讲,我可以简单地推送消息,并使用消息字符串本身作为唯一键来手动访问我的数据库以获取元数据,但出于两个原因我想避免这种情况。第一,这似乎是对 time/resources 的浪费,但第二,我希望对通知的客户端进行一些控制。我在不同的设备上遇到问题(iPad 2 vs iPhone 5s),我的代码将显示重复的推送通知,也就是说,iPad 获取推送并显示一次, iPhone 似乎收到了两次。我担心我误解了

的用法
    UIUserNotificationType allNotificationTypes =
    (UIUserNotificationTypeAlert);
    UIUserNotificationSettings *settings =
    [UIUserNotificationSettings settingsForTypes:allNotificationTypes categories:nil];
    [[UIApplication sharedApplication] registerUserNotificationSettings:settings];
    [[UIApplication sharedApplication] registerForRemoteNotifications];


    [[GCMService sharedInstance] startWithConfig:[GCMConfig defaultConfig]];

这些行以及它们如何影响锁定屏幕上显示的内容,但无论如何,如果可以确保永远不会显示重复项,我仍然宁愿进行手动控制。

您可以通过通知发送您想要的任何内容,您 iOS 设备将强制执行某些值,如果您发送以下消息,您可以显示一些消息并通过通知发送其他数据,想象一下此基础通知:

{
  aps: {
    alert: "Hi there"
  }
}

此通知将在您设备的锁定屏幕和通知栏上显示提醒消息,但也可以发送:

{
  aps: {
    alert: "Hi there",
    content-available: 1, // Add this if you want background processing
    sound: "" // If you don't want to show the notification on the notification area nor the lock screen.
  }
  data: {
    effectiveTime: ...,
    expirationTime: ...,
    message: ...,
    ...
  }
}

这将在您的设备上显示与第一个完全相同的通知,但在这种情况下,您可以使用 didReceiveRemoteNotification: 方法

对数据做任何您想做的事情
- (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo {
  NSLog(@"My data sent trough GCM: %@", userInfo[@"data"]);
}

您可以对数据使用的唯一键是 the official push notifications docs

上的 3-1 和 3-2 中列出的键

如果您想管理后台处理,根据 to the docs 您应该使用(如您所说)application:didReceiveRemoteNotification:fetchCompletionHandler:,但其他一切保持不变:

- (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo fetchCompletionHandler:(void (^)(UIBackgroundFetchResult result))handler {

  switch (application.applicationState) { 
    case UIApplicationStateInactive:
      // Do whatever you want if the app is inactive
      handler(UIBackgroundFetchResultNewData);
      break;

    case UIApplicationStateBackground:
      // Do whatever you want if the app is in background
      handler(UIBackgroundFetchResultNewData);
      break;

    case default:
      // Do whatever you want if the app is active
      handler(UIBackgroundFetchResultNewData);
      break;
  }
}