如何在iOS推送通知发出之前拦截它';锁屏通知中心上是否显示?

如何在iOS推送通知发出之前拦截它';锁屏通知中心上是否显示?,ios,objective-c,notifications,push-notification,google-cloud-messaging,Ios,Objective C,Notifications,Push Notification,Google Cloud Messaging,我正在将一个应用程序与GCM集成,以获得简单的全局主题推送通知。与GCM进行通信的服务器端是用Java/Spring编写的,并且大多数情况下工作正常。然而,我遇到了一些在iOS方面不可能解决的问题 理想情况下,我希望通过一个JSON结构(字符串格式)和一些元数据发送推送通知,而不仅仅是一个带有消息的简单字符串,因为在通知显示后,我打算将其保留在应用程序的其他地方以供查看 现在,当应用程序处于活动状态时,我没有问题,因为我的应用程序代理正在运行 - (void)application:(UIApp

我正在将一个应用程序与GCM集成,以获得简单的全局主题推送通知。与GCM进行通信的服务器端是用Java/Spring编写的,并且大多数情况下工作正常。然而,我遇到了一些在iOS方面不可能解决的问题

理想情况下,我希望通过一个JSON结构(字符串格式)和一些元数据发送推送通知,而不仅仅是一个带有消息的简单字符串,因为在通知显示后,我打算将其保留在应用程序的其他地方以供查看

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

- (void)application:(UIApplication *)application
    didReceiveRemoteNotification:(NSDictionary *)userInfo 
    fetchCompletionHandler:(void (^)(UIBackgroundFetchResult))handler {
    ....
}
它在我的主viewController中注册了一个通知,很高兴地将远程通知传递给我的viewController代码,在那里我可以解析JSON并按照自己的意愿处理它

然而,我似乎找不到一个类似的方法/过程,我可以定义它,让我对应用程序在前台不活跃时发出的通知具有相同的控制。这导致锁屏推送通知以字符串格式显示我的JSON结构,显然不是我想要的

现在,从技术上讲,我可以简单地推送消息,并使用消息字符串本身作为唯一的键来手动点击我的数据库以获取元数据,但出于两个原因,我想避免这样做。第一,这似乎是在浪费时间/资源,但第二,我希望在通知的客户端进行一些控制。我遇到的问题是,在不同的设备上(iPad2和iPhone5s),我的代码会显示重复的推送通知,也就是说,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: ...,
    ...
  }
}
这将在您的设备上显示与第一个完全相同的通知,但在这种情况下,您可以使用
didReceiveMemotentification:
方法对数据执行任何操作

- (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo {
  NSLog(@"My data sent trough GCM: %@", userInfo[@"data"]);
}
您可以用于数据的唯一键是上的3-1和3-2中列出的键

如果您想管理后台处理,根据您所说的,您应该使用
应用程序:didReceiveMemotentification: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;
  }
}

你能不能在没有留言的情况下就推一推?特别注意MansApps应答中的“内容可用”我一直在使用GCM消息中的默认设置,这导致以下结构:{aps={alert=“{\'effectiveTime\”:null,“expirationTime\”:null,“notificationId\”:1,“message\”:“Push Notification from Spring\”;};“GCM.message\u id”=“12345678”}但也许我可以根据我在这里看到的内容修改该结构:同意@remus,在您的任何代理调用您的应用程序之前,您的设备首先收到通知,因此您无法处理它,它是在操作系统级别处理的。要实现无提示通知,您可以在aps密钥中添加
声音:
,我会将其添加到答案中。因此,在连接了处理程序的didReceiveNotification中,我可以发送不包含警报的推送,然后,对于UIApplicationStateBackground,我可以生成一个本地通知,其中确实包含一个警报字段,如果我想显示消息,它会在锁屏上创建一个通知?我还没有尝试过,但理论上它应该可以工作,但请记住,如果你想要一个无声的通知,你应该使用
声音:
我理解,不是发送一个空警报。这就是我需要的,谢谢。