Notification dialog & custom notification handling on open (Legacy Version 3.5.2)

If an App does not have an inbox, message center or similar functionality to persist messages received in the app it is considered best practice to display notifications in the app on open. This ensures the user can read the notification in full after clicking on it and is not disorientated after tapping the notification if they have not fully read it.

Details on handling the notification on open to implement this or other custom functionality are given below.

iOS (Objective-C)

Push notification text can be displayed in a Custom dialog when opened on iOS. When creating a Push using the campaign creator on the XtremePush Platform or via the external API you also have the option to add a series of key, value pairs known as a payload. In this section we give an example of how you can display a custom dialog and access some payload values from the push message and perform some custom behaviour with them.

In the following example a (key, value) pair of ( t, title_text) is used to add a title to the dialog if desired, if not desired it is simply omitted. We also check for the reserved (key, value) pair of ( u, url_text) used when adding a url open action to a notification and the dialog is not displayed when redirecting to a landing page.

Sample didReceiveRemoteNotification in AppDelegate


- (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo {
    [XPush applicationDidReceiveRemoteNotification:userInfo];
    
    // Custom Handling of Push Starts Here
    // In this example if the push is a basic one we display in a dialog in the app when opened
    
    //  Retrieve the push notification text as a String from the aps dictionary
    NSString *alertText = [userInfo valueForKeyPath:@"aps.alert"];
    // Nil unless you use a title payload
    NSString *title = [userInfo valueForKeyPath:@"t"];
    
    if (userInfo[@"u"]){
        NSLog(@"Linking to a landing page");
        // Get the value of the payload with KEY = "u" used when sending the user to a landing page
        // If you want to do anything extra with it you can retrieve it otherwise do nothing
        //NSString *u = [userInfo objectForKey:@"u"];
    }
    else {
        
        // If push is a basic push we display the full text in a dialog in the App when the push is opened
        // If there was a title payload the dialog has a title
        UIAlertView *alert = [[UIAlertView alloc] initWithTitle: title
                                                        message: alertText
                                                        delegate: nil
                                              cancelButtonTitle: @"Close"
                                              otherButtonTitles: nil];
        [alert show];
    }
    
}

In this example the didReceiveRemoteNotification iOS remote notification handling method in Application delegate is modified. When a push is opened a value is retrieved from the payload by using a key to retrieve it from the dictionary. This value is used to implement some custom behaviour, in this case opening the app and displaying the push message in a dialog if the push notification is not set to open on a url (see Below).

If a URL push open action is added a dialog won’t be shown :

Sample didFinishLaunchingWithOptions in AppDelegate

The didReceiveRemoteNotification iOS remote notification handling method is not the only place where the App Delegate must be modified. When a push is opened and the app has been force closed the custom behaviour must be implemented in didFinishLaunchingWithOptions. When an app is opened from a push notification and the app is launching from a cold start the notification payload can be retrieved as shown below:


- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {

//...

// Get notification Payload if App has been opened from a notifications

   NSDictionary *pushRemotePayload = [launchOptions objectForKey:UIApplicationLaunchOptionsRemoteNotificationKey];

   NSDictionary *pushLocalPayload = [launchOptions objectForKey:UIApplicationLaunchOptionsLocalNotificationKey];

   NSDictionary *pushPayload = pushRemotePayload ? pushRemotePayload : pushLocalPayload;

   if (pushPayload) {

       // Custom processing of push notification

       NSLog(@"%@", pushPayload);

   }

The custom logic used to process the notification in didReceiveRemoteNotification

 

iOS (Swift)

 In a swift App to do the same custom dialog you must also add code to didFinishLaunchingWithOptions and didReceiveRemoteNotification

Check if app opened from notifcation on cold start 


func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {
        // Override point for customization after application launch.
 
        
        //Start - Initialise XPush  
XPush.registerForRemoteNotificationTypes(NotificationSettings.getNotificationSettings())
        XPush.applicationDidFinishLaunchingWithOptions(launchOptions)
        //End - Initialise XPush
        
        
        // Get notification Payload if App has been opened from a notification
        // Check if launched from notification
        if let userInfo = launchOptions?[UIApplicationLaunchOptionsRemoteNotificationKey] as? [NSObject : AnyObject] {
            
            handleRemoteNotification(userInfo)
            
        }
//... rest of didFinishLaunchingWithOptions

Check if app opened from notifcation on open from background or when in foreground 


    func application(application: UIApplication, didReceiveRemoteNotification userInfo: [NSObject : AnyObject]) {
        XPush.applicationDidReceiveRemoteNotification(userInfo)
        
        handleRemoteNotification(userInfo)

    }

Add a reusable function to handle notification 


func handleRemoteNotification(userInfo: [NSObject : AnyObject]) {
        // Custom processing of push notification
        let alertText = userInfo["aps"]!["alert"]
        let title = userInfo["t"]
        
        if ((userInfo["u"]) != nil){
            print("Linking to a landing page")
            // Get the value of the payload with KEY = "u" used when sending the user to a landing page
            // If you want to do anything extra with it you can retrieve it otherwise do nothing
            //u = userInfo["u"]
        }
        else{
            // Show notification in dialog
            // Do this Async - to avoid failure due to: "Attempt to present  on  whose view is not in the window hierarchy!" - i.e. attempting to display alert before app finishes loading
            dispatch_async(dispatch_get_main_queue(), {
                let alert = UIAlertController(title: title as? String, message: alertText as? String, preferredStyle: UIAlertControllerStyle.Alert)
                alert.addAction(UIAlertAction(title: "Close", style: UIAlertActionStyle.Default, handler: nil))
                self.window?.rootViewController?.presentViewController(alert, animated: true, completion: nil)
            })
        }
    }

Android

The following is an Android example of displaying a push message in a simple dialog with an OK button. The dialog will appear if a push arrives while the app is open or in the app after a user opens a push message.

Sample PushListener Android

In this example we retrieve the push message in an activity and display it in a simple dialog.

In activities where you initialise XtremePush you can import the PushMessage class.

import ie.imobile.extremepush.api.model.PushMessage;

and have your activity implement PushListener for example


public MainActivity extends ActionBarActivity implements PushListener{

Set a PushListener when initialising XtremePush as shown here:


mPushConnector = new PushConnector.Builder("XTREME_PUSH_APP_KEY", "GOOGLE_PROJECT_NUMBER")
           .setPushListener(this).create(this);

Implement the PushReceived method, this is where you will custom handle your push messages.


@Override
public void pushReceived(PushMessage pm) {

   // Your custom push handling goes here

}

The following is an example of what can be done with the push message:


@Override
public void pushReceived(final PushMessage pm) {
   if (pm == null) return;
   else if (pm.payLoadMap.isEmpty() && TextUtils.isEmpty(pm.url)) {
       // If the payload and the URL fields are empty this is a simple push and we
       // want to display push in a simple dialog when the app opens
       showAlert(pm);
   }
   else if (!pm.payLoadMap.isEmpty()){
       // Push has a payload associated custom behaviour can be implemented here
       if (pm.payLoadMap.containsKey("t")){
           showAlert(pm);
       }
   }
}

private void showAlert(PushMessage pm){
   AlertDialog.Builder builder = new AlertDialog.Builder(this);
   if(pm.payLoadMap.containsKey("t") && !TextUtils.isEmpty(pm.payLoadMap.get("t")))
       builder.setTitle(pm.payLoadMap.get("t"));
   // Add the buttons
   builder.setPositiveButton("Close", new DialogInterface.OnClickListener() {
       public void onClick(DialogInterface dialog, int id) {
           // User clicked Close button
       }
   });
   /* Set other dialog properties:
       In this example we just set the push notification text to be the message.
       The text is stored in the alert field of the PushMessage object.
       Other options that can be set are title and icon.
   */
   builder.setMessage(pm.alert);
   // Create the AlertDialog
   AlertDialog dialog = builder.create();
   // Don't forget to show it!
   dialog.show();
}

In this example when a push is received and the push has no custom payload or URL set, the text of the push message is retrieved as a String. The String is then displayed in a simple android alert dialog. The dialog has a Close button and when Close is clicked the dialog closes. This example and the payload example can be expanded upon to implement more complex custom dialogs.

 

Immediate Processing of Push Notifications in Foreground

If you are custom handling notifications  and want to immediately process messages that are received while your app is open and in the foreground there is an option to do this. If this option is used, no notification is triggered for push or location-based messages that are received while the app is open and in the foreground. Instead a message is marked as read and handled immediately. 

To use this feature, simply call the setImmediatePushProcessing() function when initialising your PushConnector object and pass in a boolean of true as the parameter:

mPushConnector = new PushConnector.Builder("XTREME_PUSH_APP_KEY", "GOOGLE_PROJECT_NUMBER")
            .setImmediatePushProcessing(true).create(this);

 

 

Have more questions? Submit a request

0 Comments

Please sign in to leave a comment.