Amazon SNS provides a cost-effective way to send push notifications to mobile devices. This is especially true for the relatively low push volume generated by something like the Roku sleep timer in Romote. Using SNS for mobile push is also supported well by the Ruby aws-sdk.
To get started using SNS, you first need to create an app in SNS to represent your application. The Amazon documentation is pretty easy to follow - you will need the APNS certificate and private key from Apple for setting up push to iOS devices.
Registering a Device
Once you have an app created, you can start registering devices with it. This is accomplished using the CreatePlatformEndpoint API and requires the device token for the iOS device. I make the registration call from the application:didRegisterforRemoteNotificationsWithDeviceToken:
callback in my application’s delegate.
Aside
I proxy all of the calls to SNS through a server that I run, so devices never communicate directly with SNS. This allows me to not expose any SNS credentials in my iOS apps as well as gives me the flexibility to change the communication with SNS (or remove SNS completely) without resubmitting the iOS apps.
Registering a device is easy using the Ruby aws-sdk:
1 2 3 4 5 6 |
|
The endpoint_arn
can then be sent back to the device to use in future push notifications (or stored for later use at the server).
Sending a Push Notification
Once a device is registered, you can send direct push notifications to that device. This is done using the Publish API. The Publish
API supports sending a different message to each supported SNS transport as well as specifying a default message; when using device-specific mobile push notifications this isn’t necessary as each device will only be using a single transport (APNS or APNS_SANDBOX is the case of iOS).
SNS supports specifying all of the keys that Apple expects in a push notification using transport-specific messages. This requires setting the MessageStructure
parameter of the Publish
call to “json” and supplying a JSON formatted object in the Message
parameter. One thing the documentation doesn’t make clear is that these need to be JSON-encoded strings and not raw JSON. An example will make this clearer:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
|
Notice the to_json
calls on lines 5, 9, and 14. Each transport key needs to be a JSON string inside the Message
parameter. Additionally, the Message
parameter itself needs to be a JSON string. Getting this wrong (by having actual JSON instead of a JSON string) leads to SNS not being able parse the Message
parameter and generates an error of “InvalidParameter: Invalid parameter: JSON must contain an entry for ‘default’ or ‘APNS_SANDBOX’”.
The value of the other_data
key is available in the userInfo
dictionary provided to the application:didReceiveRemoteNotification:
callback in your iOS application:
1 2 3 |
|
Summary
Using just a few straightforward calls, it’s possible to send push notifications to your iOS apps. SNS also supports other mobile platforms (including Google Cloud Messaging and Amazon Device Messaging) as well as broadcasting messages to subscribed devices (using topics) instead of targeting individual devices.