Monday 29 July 2013

API for communicating through MPNS

I developed an API for communicating through MPNS with Windows Phone mobile devices ([1]). For this, I designed a way of building the messages, sending them and handling the result.
To communicate with MPNS servers, I need to send POST requests, so I decided to use Conduit, as I have done with GCM. The MPNS Api looks like this:

MPNS let you send notification in an authenticated or unauthenticated mode, so you can configure this with  MPNSAppConfig:
 data MPNSAppConfig = MPNSAppConfig{
        numRet       :: Int      -- def = 5
    ,   useSecure    :: Bool     -- def = False
    ,   certificate  :: String   -- def = ""
    ,   privateKey   :: String   -- def = ""
    }
To build messages, I developed a data type "MPNSmessage"
 data MPNSmessage = MPNSmessage{
        deviceURIs          :: [DeviceURI]  -- destinations
    ,   batching_interval   :: MPNSInterval -- Immediate | Sec450 | Sec900
    ,   target              :: MPNSType     -- Toast     | Raw    | Tile
    ,   restXML             :: Document     -- the XML data to be sent
    }
For sending notifications:
sendMPNS :: Manager -> MPNSAppConfig -> MPNSmessage -> IO MPNSresult
Last, for handling the result:
 data MPNSresult = MPNSresult{
        sucessfullResults :: [(DeviceURI,MPNSinfo)]
    ,   errorException    :: [(DeviceURI,CE.SomeException)]
    }

The code is available on GitHub:
 The MPNS Api : [1]
 Test example for MPNS: [2]

For more information about:
 The MPNS Service: [3]
 The communication with MPNS servers:  [4]

Microsoft Push Notification Service

The Microsoft Push Notification Service in Windows Phone is an asynchronous, best-effort service that offers third-party developers a channel to send data to a Windows Phone app from a cloud service in a power-efficient manner.

The process of registration is very similar to the rest of push services. The app requests a push notification URI from the Push client service, and then it sends it to your cloud service.
When you have info to send, you use the notification URI to send a push notification to MPNS servers, and MPNS routes the push notification to your app.

Depending on the format of the push notification and the payload attached to it, the info is delivered as raw data to the app, the app's Tile is visually updated, or a toast notification is displayed.
MPNS returns a response code to your cloud service after a push notification is sent indicating that the notification has been received and will be delivered to the device at the next possible opportunity.
Also, in a response code, you can get information about the state of the device (Connected / Temp Disconnected / Disconnected). For more information: [1]

When communicating with MPNS servers, you have to send POST messages for each Windows Phone device to which you want to send a notification. You have to specify the appropriate notification type (Raw / Tile / Toast), the destination Uri, and the rest of information in a XML format.
If you want to send multiple notifications, you must create separate POST messages for each notification. This is one of the differences with GCM, where you can send multicast messages in a single POST request.


Tuesday 16 July 2013

API for communicating through APNS

I developed an API for communicating through APNS with iOS mobile devices ([1]).
For this, I designed a way of building the messages, sending them and handling the result.
One important thing that I had to take into account, was how to maintain the connection. For APNS, I needed to communicate through a streaming SSL connection, so I couldn't use conduit as I 've done with GCM. So, to face this problem, I developed an APNSManager.
The API looks like this:

 startAPNS     :: APNSAppConfig -> IO APNSManager  
 closeAPNS     :: APNSManager   -> IO ()  
 sendAPNS      :: APNSManager   -> APNSmessage -> IO APNSresult  
 feedBackAPNS  :: APNSAppConfig -> IO APNSFeedBackresult  

The main idea is:

- First of all, the sevice is started with: 'startAPNS'.
  This function:
    * Creates a channel to put the notifications to be sent.
    * Starts a worker thread, which maintains the connection with APNS servers, and sends the data it receives through the cannel.
    * Returns an APNSManager.

- Then, I can use 'sendAPNS' to send messages. Every time I call it:
    * It puts the message on the channel.
    * Wait until the time the message is taken by the worker thread.
    * When the message is taken from the channel, the worker thread will send me a duplicate copy of the error channel. So, I will wait for the end of the sending, or an error msg through the error channel.
    * I return the appropiate result depending on a successful or not operation.

- I stop the service with 'closeAPNS'. It kills the worker thread.

The worker identifies each message it sends with a number, which is sent to APNS. If an error ocurred, this number is returned in an error messages by the APNS servers, representing the number of the last message that was successfully sent.
Then, the worker continually sends messages until it receives an error message. In this case, it resends the error message to the error channel for all the threads waiting for a response, and then it restarts itself, because after an error, APNS servers close the connection.
The time we wait for an error response, after having sent all the messages, can be stablished with the timeoutLimit parameter, when creating a Manager.

As to use this service, Apple requires you to be an enrolled iOS Developer or something similar, I decided to test the API with a local server. This server was taken from: [3] . It simulates the APNS servers and I modified it to test different common scenes.

The code is available on GitHub:
 - The APNS Api : [1]
 - Test example for APNS: [2]

For more information about:
 - The APNS Service: [4]
 The communication between providers and APNS servers:  [5]


Monday 15 July 2013

Apple Push Notification Service

Apple Push Notification service is a robust and highly efficient service for propagating information to devices iOS. Each device establishes an accredited and encrypted IP connection with the service and receives notifications over this persistent connection.

To send notifications, the provider connects to APNS through a permanent and secure connection. When there is new information to be sent, the provider prepares and sends a notification through the APNS channel, which pushes the notification to the target device.


(https://developer.apple.com/library/ios/documentation/NetworkingInternet/Conceptual/RemoteNotificationsPG/Art/remote_notif_simple_2x.png)

A notification is a short message consisting of two main parts of data: the device token and the payload:
  * The device token identifies the device and application on the client side.
  * The payload is a JSON-defined property list that specifies how the user of an application on a device is to be alerted.

Each provider requires a unique provider certificate and private cryptographic key for validation of its connection to the APN. This certificate, provisioned by Apple, must identify the particular topic published by the provider; the topic is the bundle ID of the client application.

For more information: Apple Developers - Apple Push Notification Service