Notification dialog & custom notification handling on open (Legacy XPush_Android 4.3, XPush_iOS 3.3)

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 MessageResponseListener Android

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

In your Application.java where you initialise XtremePush, you can import the PushMessage class.

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

and have your Application class implement MessageResponseListener for example:

public class YOUR_APPLCIATION extends Application implements MessageResponseListener{

Set a MessageResponseListener when initialising XtremePush as shown here:


new PushConnector.Builder("XTREME_PUSH_APP_KEY", "GOOGLE_PROJECT_NUMBER")
            .setMessageResponseListener(this)
            .create(this);

Implement the messageResponseReceived method, this is where you will custom handle your response messages.

@Override
public void messageResponseReceived(String messageType, PushMessage messagePayload,
            String responseType, HashMap<String, String> responsePayload,
            WeakReference<Context> uiReference) {

}

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

@Override
public void messageResponseReceived(String messageType, PushMessage messagePayload,
            String responseType, HashMap<String, String> responsePayload,
            WeakReference<Context> uiReference) {
    if (uiReference.get() != null) {
        showAlert(null, (Activity)uiReference.get(), messageType, responseType);
    }
}

private void showAlert(PushMessage pm, Activity activity,
            String messageType, String responseType) {
    AlertDialog.Builder builder = new AlertDialog.Builder(activity);
    // 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 alert to be a description of both
        the type of message and how it was handled by the user
    */
    String message = "User Received an "+messageType+" message \nwhich they "+responseType+"ed";
    builder.setMessage(message);
    // Create the AlertDialog
    AlertDialog dialog = builder.create();
    // Don't forget to show it!
    dialog.show();
} 

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:

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

 

 

 

Have more questions? Submit a request

0 Comments

Article is closed for comments.