com.APNS.EncodeMessage

Encodes an APNS specific push notification message into a BYTE.

Important:

On March 31 2021 Apple® discontinued the APNs legacy binary protocol. Therefore, the com.APNS class is now desupported. The documentation pages related to the APNS binary protocol are still provided for information. Contact your support center, if you need to implement APNS with the new HTTP/2-based provider API.

Starting with Genero V5.00, the com.APNS classe will be removed from the com package.

Syntax

com.APNS.EncodeMessage(
   data BYTE,
   deviceIdBase64 STRING,
   json STRING,
   uuidBase64 STRING,
   expiration INTEGER,
   priority INTEGER)
  RETURNS INTEGER
  1. data defines a BYTE variable holding the APNs message. This BYTE variable must be located IN MEMORY.
  2. deviceIdBase64 defines an APNs device token (encoded in Base-64).
  3. json defines a JSON string containing the APNs push message data.
  4. uuidBase64 defines the 4 bytes-long push message identifier (encoded in Base64).
  5. expiration defines a number of seconds since UNIX® Epoch defining the expiration date of the message.
  6. priority defines an integer as the priority of the message.

Usage

This method builds the APNS push notification message into a BYTE variable, for a given device token. This BYTE variable must be located IN MEMORY.

The size of an APNS notification payload cannot exceed 2 Kilobytes. Make sure that the resulting BYTE variable does not exceed this size limitation. If more information needs to be passed, after receiving the push message, apps must contact the server part to query for more information. However, this is only possible when network is available.

The APNS push notification message protocol requires some binary data to be encoded in the message content before it is sent to the APNS server with a TCP (over SSL/TLS) request, to specific URIs, namely:
  • "tcps://gateway.sandbox.apple.com:2195" (for development)
  • "tcps://gateway.push.apple.com:2195" (for production)

You need to provide several parameters in order to build the push notification message:

The deviceToken parameter is an APNS device token encoded in Base-64. It's used to identify the target device that must receive the push message. The device token identifies a single iOS device: If you have N devices registered to your push notification provider, you will have N different device tokens. If you want to send one push notification message to all the devices, you must send N different messages, where the only difference between the messages is the device token.

It's in your hands to handle the list of registered device tokens. A device token is assigned to a physical iOS device when the mobile app issues a mobile.registerForRemoteNotifications front call. The app must then provide its device token to the push provider program using a method such as a web service mechanism.

Fill the json parameter with a JSON string containing the APNS push message data. For example:
LET json = '{"aps":{"alert":"Hello, world","sound":"default","badge":1,"content-available":1}}'

See APNS documentation for more details about the JSON content of a message.

The uuid parameter is the 4 bytes-long push message identifier, encoded in Base64. This parameter can be used later to identify the message in push notification errors (com.APNS.DecodeError). This parameter can be NULL. To create the uuid parameter, use the security.RandomGenerator.CreateRandomString API, with a size of 4:
LET uuid = security.RandomGenerator.createRandomString(4)
The expiration parameter is a number of seconds since UNIX Epoch. It defines the expiration date of the message if it can not be sent by the APNS server to the target devices. This parameter can be NULL, to indicate that there is no expiration date:
LET dt = CURRENT + INTERVAL (10) MINUTE TO MINUTE
LET expiration = util.Datetime.toSecondsSinceEpoch(dt)
The priority parameter can be used to define a priority for the push notification message. Typically, use a value of 10 for immediate, 5 for delayed. This parameter can be NULL. See APNS documentation for more details.

If there's an encoding error, the method will raise the exception -15566, with details in the sqlca.sqlerrm register.

Example

DEFINE push_data BYTE,
       deviceTokenHexa STRING,
       dt DATETIME YEAR TO FRACTION(3),
       expiration INTEGER,
       json_data STRING,
       uuid STRING

LOCATE push_data IN MEMORY

LET deviceTokenHexa = "84e3................."

LET dt = CURRENT + INTERVAL (10) MINUTE TO MINUTE
LET expiration = util.Datetime.toSecondsSinceEpoch(dt)

LET json_date = util.JSON.stringify(...)

LET uuid = security.RandomGenerator.createRandomString(4)

CALL com.APNS.EncodeMessage(
             push_data,
             security.HexBinary.ToBase64(deviceTokenHexa),
             json_data,
             uuid,
             expiration,
             10
       )

IF LENGTH(push_data) > 2000 THEN
   -- Must reduce the message content...
   RETURN FALSE
END IF

-- Do the TCP request with the push_data variable
...

For a complete example, see APNs push provider.