Thursday, January 11, 2018

Mobile Push Notifications with Lightstreamer Server 7.0 and Client SDKs 4.0

With the upcoming release of Lightstreamer 7.0, and its beta 2 already available for you to test, Mobile Push Notifications APIs jump on the Unified Client API model with SDKs version 4.0, employing a new asynchronous model and delivering all the latest features of iOS and Android push notifications.

In this blog post we take a look at the new APIs, with code examples and use cases for both Objective-C and Java.

Note: if you need download and example pointers, jump directly to the end of the post ("Get the SDKs").

Quick Recap of Mobile Push Notifications

Mobile Push Notifications (or MPN for short) are handled by Lightstreamer as an alternative route for real-time updates. This means that they are backed by a subscription and by a data/metadata adapter pair, like any common real-time subscription. This also means that, if you have already integrated Lightstreamer in your service, adding push notifications to your app is a client-only trivial task.

Once an MPN subscription is activatedthe Server, instead of sending updates on the session's stream connection, forwards them to an MPN service provider appropriate for the client's platform (APNs for Apple platforms and FCM for Google platforms). MPN subscriptions are stored on an SQL database and consumed directly on the Server, with no need for the app to be online or connected.

The following requirements must be met for Lightstreamer MPN APIs to work properly:
  1. The Lightstreamer Server must have the MPN Module enabled. This also requires an SQL DB available and configured.
  2. The data/metadata adapter pair must expose items in MERGE or DISTINCT modes. COMMAND, RAW and unfiltered modes can't be used for push notifications, together with the selector property.
  3. On iOS, your app must register for Remote Notifications using common iOS APIs. The Lightstreamer client takes charge once the device token is available.
  4. On Android, the Lightstreamer client can do this for you using Firebase APIs, or alternatively your app can do it manually and then let the client take charge once the device token is available.

The Device Token's Lifecycle

Depending on the lifecycle of the app and the device it's installed on, the token may be subject to a number of events, e.g. expiration, invalidation etc. By saving the device token on a local, restorable storage (NSUserDefaults on iOS, SharedPreferences on Android), both the client SDKs ensure they can handle these events automatically.

In particular:
  • App deletion/uninstall: if the app is deleted/uninstalled the token is invalidated. The Server detects an invalid token and suspends sending of push notifications. The suspension lasts for a configurable grace period, during which MPN subscriptions are maintained. If the grace period expires, the token and its subscriptions are deleted.
  • App restore/reinstall on the same device: if the app is restored/reinstalled within the grace period, the Server reactivates the MPN subscriptions and restarts sending push notifications. If it is reinstalled after the grace period, the token is accepted as new.
  • App restore/reinstall on a different device: if the app is restored/reinstalled on a different device (i.e. from a backup), the client detects the token change and sends both the previous and the new token to the Server, which can then move previous MPN subscriptions to the new device and restart sending push notifications.
  • Expiration: if the token expires, the system provides the app with a new token. In this case the client detects the token change and sends both the previous and the new token to the Server, which can then update existing MPN subscriptions and continue sending push notifications.

So, the first step to use the new MPN APIs is to obtain a device token and create an MPN device object.

See the following examples:

Obtaining the Device Token on iOS

Registration for Remote Notifications is usually implemented in the app delegate:


Obtaining the Device Token on Android

If the Lightstreamer client obtains the token for you from Firebase:

If you obtain the token manually:


Registering the Device

Once the app has created an MPN device object, it must be passed to the Lightstreamer Server so that it can be registered on its database.

Device registration, like most of the operations in the Unified Client API model, is an asynchronous operation and may be requested immediately after a connection, even if the connection is still ongoing. The request is enqueued and executed as soon as possible.

See the following examples:

Connecting and Registering the Device on iOS



Connecting and Registering the Device on Android



Creating and Activating an MPN Subscription

Since updates from an MPN subscription are delivered as push notifications, you have to specify how to map the subscription's fields to the notification payload. With new MPN APIs, you do this by providing directly the JSON structure to be used with the MPN service provider. The structure, that can be set in the notificationFormat property of the MPN subscription, may contain references to fields in the forms ${field_name} (a named argument) or $[field_index] (an indexed argument). These references are replaced by the Server with the content of the update.

To help filling this structure, an MPN builder class has been added that knows the appropriate structure for your MPN service provider and can build the notification format for you. In this way you don't need to dive into the APNs or FCM message format documentation.

Subscribing to an MPN subscription is again an asynchronous operation: it can be requested immediately after device registration, even if the registration is still ongoing. The request is enqueued and executed as soon as possible.

See the following examples:

Activating an MPN Subscription on iOS



Activating an MPN Subscription on Android




Other Features of MPN Subscriptions

MPN subscriptions are based on real-time subscriptions, and as such they employ similar semantics. E.g. you can specify one item, multiple items or a group ID, a schema name or a list of fields, a maximum frequency, a buffer size etc. 

Additionally to common subscription parameters, and similarly to old MPN APIs, MPN subscriptions also provide two peculiar features:
  • subscription coalescing, and
  • trigger expression.

Coalescing MPN Subscriptions

MPN subscriptions are persistent entities associated with the device. They survive the session, of course, or they could not be able to send push notifications when the app is offline. Hence, your app must be aware if an MPN subscription is already active or not: activating the same MPN subscription multiple times would lead to receiving the same notification multiple times.

However, if you specify the coalescing flag as YES/true during activation, the MPN subscription is coalesced into any existing one that has the same base parameters.

Base parameters are:
  • Adapter set
  • Data adapter
  • Items or group ID
  • Fields or schema name
  • Trigger expression

The coalescing flag comes of help when your app needs a fixed set of MPN subscriptions to be always active. In this simplified case, your app can safely create and activate the MPN subscriptions it needs at startup (specifying the coalescing flag as YES/true) and then forget about them. Even if these subscriptions are activated multiple times, in particular each time the app is started, the Server will keep just one for each set of base parameters.

On the other hand, if your app needs a variable set of MPN subscriptions, you need to verify which is already active and which is not, before activating new ones. More on this later.

Using Trigger Expressions

MPN subscriptions can operate in two different ways:
  • If no trigger expression is specified, which is the default, each update results in a push notification being sent (unless frequency restrictions apply).
  • If a trigger expression is specified, each update is tested against the expression, and only if it evaluates to true a push notification is sent. Moreover, after this push notification, the subscription is suspended.

Trigger expressions are valuable tools in situations where you would need additional logic on the adapter to implement decisions that are specified on the client. Some examples:
  • A trader wants a notification when a stock price raises over a certain threshold.
  • A user wants a notification when their name is cited in a chat room.
  • A recipient wants a notification when a package being delivered gets within a certain distance.

Adding bits of logic like these on the adapter side requires a measurable effort and a rolling restart of the Server, while specifying them as simple expressions on the client-side, directly on the MPN subscription, is trivial.

Trigger expressions must be specified as a string containing a Java language boolean expression, even on the iOS platform. It can include references to fields in the form of named or indexed arguments, evaluated as strings. The expression can be set with the triggerExpression property of the MPN subscription. Syntax verification, compilation and evaluation are performed on the Server.

The examples above could be specified as follows:
  • Stock price above a threshold: Double.parseDouble(${last_price}) > 100.0
  • Name cited in a chat room: ${message}.indexOf("MyNickName") >= 0
  • Package coordinates within 7 miles of Manhattan, NY (consider that 1° ≈ 70 miles): Math.sqrt(Math.pow(Double.parseDouble(${lat}) - 40.758896, 2.0) + Math.pow(Double.parseDouble(${long}) - -73.985130, 2.0)) < 0.1

As you see, possibilities are endless.

Managing MPN Subscriptions

Since new MPN APIs are asynchronous, inquiry operations of old MPN APIs are now no more necessary. They have been replaced by events that notify when the list of existing MPN subscriptions is available, and a property on Lightstreamer client object, MPNSubscriptions, to access them.

See the following examples:

Checking Currently Active MPN Subscriptions on iOS



Checking Currently Active MPN Subscriptions on Android




MPN subscriptions can be modified in place, without the need to first unsubscribe them, by using the copy constructor. The copy inherits the unique ID of the MPN subscription, and when it is submitted for activation through the Lightstreamer client object, the Server uses its properties to update the existing subscription.

See the following examples:

Modifying an Active MPN Subscription on iOS



Modifying an Active MPN Subscription on Android




Last but not least, MPN subscriptions may be deactivated singularly, by specifying the MPN subscription object, or collectively, by specifying their status. This second option is useful, for example, to quickly clean up all the MPN subscriptions that are already triggered.

See the following examples:

Deactivating MPN Subscriptions on iOS



Deactivating MPN Subscriptions on Android




The Metadata Adapter

The metadata adapter maintains its role of authentication and authorization of MPN operations also with Server version 7 and new APIs. The 3 events related to MPN are the following:




The purpose of the 3 events is unchanged compared to Server 6.x. The only difference is the addition of sessionID in the method signature and the elimination of platform-specific subclasses of MpnSubscriptionInfo (this object now provides the same notificationFormat property found on the client, subclasses are no more needed).

More in detail:

NotifyMpnDeviceAccess(String user, String sessionID, MpnDeviceInfo device) 

This notification provides a chance to authorize a user to access to a certain device, specified by:
  • Platform: either "Apple" or "Google"
  • Device token
  • App ID, corresponding to the bundle ID for Apple platforms and the package name for Google platforms

For instance, here you can cross-validate the device token with an external database.

NotifyMpnSubscriptionActivation(String user, String sessionID, TableInfo table, MpnSubscriptionInfo mpnSubscription) 

This notification provides a chance to validate the parameters of the MPN subscription, including:
  • Items
  • Fields
  • The notification format
  • The trigger expression
  • The device, specified by platform, token and app ID

For instance, if a certain item must be visible via real-time subscriptions but not via push notifications, this is the correct place to check and block its access.

NotifyMpnDeviceTokenChange(String user, String sessionID, MpnDeviceInfo device, String newDeviceToken)

This notification provides a chance to authorize a token change by a certain user on a certain device. The device is specified by platform, token and app ID.

For instance, here you can cross-validate the new device token with an external database before accepting it.

Documentation and Examples

The General Concepts document, included in the Server distribution, has an updated and expanded chapter 5 dedicated to MPN. Here you can find details about:

  • Server configuration
  • Device and subscription lifecycles
  • Trigger expression specifications
  • Database compatibility
  • Full workflow sequence diagram

Have a look before starting your integration journey.

The MPN Stock-List demos for iOS and Android have also been updated to the new APIs and are available on GitHub:

Their distributions on the corresponding app stores have also been updated and are available for you to test.

As usual, if you have any feedback leave a comment or contact us at support@lightstreamer.com.


Get the SDKs

Lightstreamer Client Library for iOS version 4.0.0

Requirements

  • Requires Lightstreamer Server version 7.0 b2 or greater
  • Includes 32 bit, 64 bit and bitcode segments (plus i386 and x64 segments for use with the simulator)
  • Requires iOS version 8.0 or greater
  • Requires linking with the following frameworks and libraries: SystemConfiguration.framework, Security.frameworkiconv
  • Requires ARC

Download Links

Lightstreamer Client Library for Android version 4.0.0

Requirements 

  • Requires Lightstreamer Server version 7.0 b2 or greater
  • Requires Android version 4 or greater

Download Links

SDKs for Additional Apple Platforms

These platforms support push notifications, although some limitations.

Lightstreamer Client Library for macOS version 4.0.0

Requirements

  • Requires Lightstreamer Server version 7.0 b2 or greater
  • Requires macOS version 10.9 or greater
  • Requires linking with the following frameworks and libraries: SystemConfiguration.frameworkSecurity.frameworkiconv
  • Requires ARC

Download Links

Lightstreamer Client Library for tvOS version 4.0.0

Requirements 

  • Requires Lightstreamer Server version 7.0 b2 or greater
  • Includes 64 bit and bitcode segments (and x64 segment for use with the simulator)
  • Requires tvOS version 9.0 or greater
  • Requires linking with the following frameworks and libraries: SystemConfiguration.frameworkSecurity.frameworkiconv
  • Requires ARC

Download Links

No comments:

Post a Comment

Note: Only a member of this blog may post a comment.