+

Search Tips   |   Advanced Search

Use native and JavaScript push APIs in the same app

We can use Native and JavaScript push APIs in the same MobileFirst app.

MPF provides two sets of APIs to handle push notifications - native and web (JavaScript). Each of these APIs on its own allows the application to handle push notifications in its native/JavaScript environment. However, we can also use both API types in the same app, provided you follow certain restrictions:

iOS

Both APIs rely on an automatic process to initialize push support, triggered when connecting to the MobileFirst Server. In case the first connection to the server is made from native code, the Native API must be used for the Push management operations throughout the app lifecycle (subscribe, unsubscribe, registerEventSourceCallback, and others). If the first connection is made form the JavaScript code, the JavaScript API must be used for these operations.

Android

In the Android Environment, there is a stronger restriction. The native Push API cannot be used in a hybrid application. The JavaScript API must be used for Push management operations (subscribe, unsubscribe, and others).


Reacting to push notifications

It is possible to react to push notifications both in native and JavaScript code in the same app. Using both provides an enhanced user experience because it allows the app to react to push notifications in the appropriate context. To achieve the use of both:

Use a native API for managing push operations (iOS only)

If we are coding in native iOS to handle the received push, forward the data to JavaScript using the Action Sender API.

Here is an example of JavaScript code:

// register an action receiver function 
WL.App.addActionReceiver("myActionReceiverID", myActionReceiver);
// define action receiver function 
function myActionReceiver(received)
{
  if (received.action == "handlePushFromNative")
  {
    // handle notification - do something with received.data
}
In iOS native code, push notification is handled by the following method:

    (void)application:(UIApplication*)application didReceiveRemoteNotification:(NSDictionary*)userInfo

in the implementation of the MyAppDelegate interface. For example:

(void)application:(UIApplication*)applicationdidReceiveRemoteNotification:(NSDictionary*)userInfo
{
  BOOL shouldHandleInNative = some applicative logic;
    if (shouldHandleInNative)
    {
      // handle notification in native code     }
    else
    {
      // send the push data to a Javascript action receiver 
        [[WL sharedInstance]sendActionToJS:@"handlePushFromNative" withData:userInfo];
    }
}

Use a JavaScript API for managing push operations

When the JavaScript API is used to handle push, the push notifications are handled by the JavaScript callback function that is registered using the API function WL.Client.Push.registerEventSourceCallback (alias, adapter, eventSource, callback). To handle the notifications using the native code of the app, code as follows:

In JavaScript code

Define and register a callback handler for the push notifications. For example:

WL.Client.Push.registerEventSourceCallback(
  "myPush", 
  "PushAdapter", 
  "PushEventSource", 
  pushNotificationReceived
);
function pushNotificationReceived(props, payload) {
  alert("pushNotificationReceived invoked");
  alert("props :: " + JSON.stringify(props));
  alert("payload :: " + JSON.stringify(payload));
}

In native Android code

  1. Add a default constructor to the GCMIntentService.java class. For example:
    public GCMIntentService(){
      super();
      setBroadcastReceiver(new BroadcastReceiver() {
        @Override
        public void onReceive(Context context, Intent intent) {
          //This is Empty Broadcast Receiver, do not implement any logic here     }
      });
    }

  2. In a custom native activity, implement the logic for handling the received push notification. Define a new broadcast receiver. For example, we can implement it in the onStart method of the native activity, as follows:
    @Override
    protected void onStart() {
      super.onStart();
      //Action name for inner push messages
      String action = getPackageName() + "." + getString(R.string.app_name) + ".C2DM_MESSAGE";
      //Register Custom Push Broadcast Receiver
      registerReceiver(new BroadcastReceiver() { 
        @Override
        public void onReceive(Context context, Intent intent) {
          if (isHandleInNative){ //Some variable controlled by applicative code  
          Message message = intent.getParcelableExtra("message");
          // Custom Native Logic here using the Message class, use message.toString() 
          // to receive the JSON object with push notification data. 
          //Abort will prevent from sending the broadcast to hybrid part       abortBroadcast();
        }
      }, new IntentFilter(action));
    }

In native iOS code Add the method

    -(void)application:(UIApplication*)application didReceiveRemoteNotification:(NSDictionary*)userInfo

to the implementation of the MyAppDelegate interface. The method should implement the following logic:

- (void)application:(UIApplication*)application didReceiveRemoteNotification:(NSDictionary*)userInfo
  {
    BOOL shouldHandleInNative = some applicative logic;
    if (shouldHandleInNative)
    {
      // handle notification     }
    else
    {
      // call the worklight framework implementation - this will 
      // invoke the Javascript callback handler
      [super application:application didReceiveRemoteNotification:userInfo];
    }
  }


Parent topic: Push notification