Receiving a Push Notification

The reception handler and the user action handler receive Push to User notifications.

The following sample code is for getting notification content with the application(_:didReceiveRemoteNotification:fetchCompletionHandler:) method of the AppDelegate class.

Swift:

func application(_ application: UIApplication, didReceiveRemoteNotification userInfo: [AnyHashable: Any], fetchCompletionHandler completionHandler: (UIBackgroundFetchResult) -> Void) {
  print("Received notification : \(userInfo)")

  // Create a KiiReceivedMessage instance from userInfo.
  let message = KiiReceivedMessage(fromAPNS: userInfo)

  // Get the sender of the push message.
  if (message.senderUser() != nil) {
    // If the sender is a user, get the user.
    let aUser = message.senderUser()
    // Refresh the user and then access it.
  } else if (message.senderThing() != nil) {
    // If the sender is a thing, get the thing.
    let aThing = message.senderThing()
    // Refresh the thing and then access it.
  } else {
    // The message has no sender information.
  }

  // Extract the target scope.
  let scopeType = message.getValueOf(.SCOPE_TYPE)!
  switch(scopeType){
  case "APP_AND_GROUP" :
    // If the subscribed topic is in a group scope, get the group.
    let aGroup = message.eventSourceGroup()
    // Refresh the group and then access it.
    break
  case "APP_AND_USER" :
    // If the subscribed topic is in a user scope, get the user.
    let aUser = message.eventSourceUser()
    // Refresh the user and then access it.
    break
  case "APP_AND_THING" :
    // If the subscribed topic is in a thing scope, get the thing.
    let aThing = message.eventSourceThing()
    // Refresh the thing and then access it.
    break
  default:
    // The subscribed topic is in the application scope.
    break;
  }

  // Get the topic name.
  let topicName = message.getValueOf(.TOPIC)

  // Get the topic.
  let aTopic = message.eventSourceTopic;

  completionHandler(.newData)
}

Objective-C:

- (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo fetchCompletionHandler:(void (^)(UIBackgroundFetchResult result)) completionHandler {
  NSLog(@"Received notification: %@", userInfo);

  // Create a KiiReceivedMessage instance from userInfo.
  KiiReceivedMessage *message = [KiiReceivedMessage messageFromAPNS:userInfo];

  // Get the sender of the push message.
  if (message.senderUser != nil) {
    // If the sender is a user, get the user.
    KiiUser *aUser = message.senderUser;
    // Refresh the user and then access it.
  } else if (message.senderThing != nil) {
    // If the sender is a thing, get the thing.
    KiiThing *aThing = message.senderThing;
    // Refresh the thing and then access it.
  } else {
    // The message has no sender information.
  }

  // Extract the target scope.
  NSString *scopeType = [message getValueOfKiiMessageField:KiiMessage_SCOPE_TYPE];
  if ([@"APP_AND_GROUP" isEqualToString: scopeType]) {
    // If the subscribed topic is in a group scope, get the group.
    KiiGroup *aGroup = message.eventSourceGroup;
    // Refresh the group and then access it.
  } else if ([@"APP_AND_USER" isEqualToString: scopeType]) {
    // If the subscribed topic is in a user scope, get the user.
    KiiUser *aUser = message.eventSourceUser;
    // Refresh the user and then access it.
  } else if ([@"APP_AND_THING" isEqualToString: scopeType]) {
    // If the subscribed topic is in a thing scope, get the thing.
    KiiThing *aThing = message.eventSourceThing;
    // Refresh the thing and then access it.
  } else {
    // The subscribed topic is in the application scope.
  }

  // Get the topic name.
  NSString *topicName = [message getValueOfKiiMessageField:KiiMessage_TOPIC];

  // Get the topic.
  KiiTopic *aTopic = message.eventSourceTopic;

  completionHandler(UIBackgroundFetchResultNewData);
}

This sample code gets information from the KiiReceivedMessage instance as follows:

  1. Get the user or the thing that sent the push notification to the topic with the senderUser() method or the senderThing() method.

  2. Extract the following fields from the notification with the getValueOf(_:) method.

    • .SCOPE_TYPE: The scope of the topic
    • .TOPIC: The name of the target topic
  3. Get the KiiTopic instance from the eventSourceTopic property.

For more information about interpreting push notifications and extracting field values, see the appledoc.

If your mobile app will receive Push to User notifications via Notification Center, implement the user action handler as well. As with the sample code in this topic, the sample code for the user action handler shows how to get the payload content from the KiiReceivedMessage instance.

The reception handler and the user action handler might be successively called or called multiple times for a single notification. You might need to develop additional functions such as that for deleting duplicated processes. For understanding when and what methods are called, see Combinations of Reception Methods.

If you have issues in receiving push notifications, information in Troubleshooting might help you. You can also use the simple implementation illustrated in Push Notification Tutorials to investigate if the push notification is working properly.

Determining the type of push notification

The reception handler and the user action handler receive all push notifications to the mobile app.

You can determine which feature (Push to App, Push to User, or Direct Push) generated a push notification that was received on the mobile app by checking keys in the payload. For available fields by feature, see KiiReceivedMessage in the appledoc. Determine the type of push notification according to the information in the appledoc.

Push message example

The following is an example of the data you can get from userInfo. You can get various information from the push message, such as the topic that sent the notification and the custom data specified by the application (in this example Key1 = Value1). For more information, see the appledoc.

{
    aps =     {
        alert =         {
            body = Alert;
        };
        badge = "-1";
    };
    Key1 = Value1
    s = "01234567-89ab-cdef-0123-456789abcdef";
    sa = 0123abcd;
    st = "APP_AND_USER";
    su = "01234567-89ab-cdef-0123-456789abcdef";
    to = myTopic;
    w = 1403844623139;
}

Preventing an infinite loop of push notifications

When designing and implementing the push notification feature, ensure that your mobile app does not cause an infinite loop of push notifications. If the notification reception process triggers another push notification, there is no way to stop the infinite loop.

Specifically for the Push to User notification feature, if the notification reception process sends a push message to the subscribed topic, it will cause an infinite loop.

If your release module caused an infinite loop, it would be very difficult to solve the issue. To fix it fundamentally, your mobile app on every end-user's device must be updated to a fixed version. Until the update is complete, you would need to delete the key or the certificates in the developer portal or unsubscribe each user from the bucket by using the REST API.