Sending iOS push notifications from robotmia

Introduction

robotmia makes it simple to send iOS push notifications through the Apple Push Notification service (APNs). Once you are set up, you'll be able to use the robotmia website to send pushes to your users as easily as you send an email. To get started, you need to:

  1. Configure your app for push notifications by creating an App ID and corresponding Provisioning Profile
  2. Enable iOS push notifications in robotmia by uploading your app's SSL push certificate
  3. Add your users' device tokens to their robotmia People profiles using our iOS lib or API

This guide will help you set up a Sandbox APNS environment and test sending push notifications. Setting up production certificates is slightly different and will not be covered in this tutorial. If your app is already configured to receive push notifications feel free to skip ahead to the next section of this guide.

Configuring your app for push notifications

Your app must first be configured and built with an App ID and Provisioning Profile configured to use the Apple Push Notifications service.

To begin, log in to the iOS developer center and browse to Certificates, Identifiers & Profiles.

Set up your App ID

Select "App IDs" under the "Identifiers" section of the left-hand navigation pane and click the plus icon to the top-right of the UI to create a new App ID.

Give your App ID a descriptive name - then make sure the App ID prefix and Bundle ID are correct. Your Bundle ID should match the Bundle ID of your app in Xcode. Make sure to check "Push Notifications" under App Services, then click Continue.

Once created, click your new App ID and then click Edit.

Generate your APNs certificate

Scroll down to "Push Notifications" and click "Create Certificate..." under "Development SSL Certificate". This will begin the APNS cert generation process.

Make sure to read the directions on the first page of the wizard ("About Creating a Certificate Signing Request") before clicking "Continue".

Once the certificate is ready simply download and double-click the file to add the credentials to Keychain Access. You'll need Keychain Access again in a few steps so you might want to keep it open - for now, go back to the Certificate portal to create a Provisioning Profile.

Set up your Provisioning Profile

Select "Development" under the "Provisioning Profiles" section of the left-hand navigation pane and click the plus icon to the top-right of the UI to create a Provisioning Profile for your newly-created App ID.

Select "iOS App Development" as the profile type and click "Continue". You'll then be asked for the App ID to link this profile to - select the one created in the previous steps, then "Continue".

On the next page you'll be prompted to select a Developer certificate - make sure you choose the identity you use for Xcode (this is generally the same as the user credentials you logged in to the Developer Portal with).

You'll then be asked to select the iOS devices you plan on testing the app on. This guide assumes you want to test on a single device, but you're free to select up to 15 iOS devices in this modal. You must add the specific devices you plan to run the app on - if you do not see the device listed, you'll need to register the device through the "Devices" section of the Developer Portal or through Xcode.

Verify that the settings look correct, then click "Generate". You can then download the new Provisioning Profile - just double click the file to add it to Xcode.

Enabling push notifications in robotmia

Before you can send push notifications with robotmia, you have to export and upload your Apple Push certificate.

Export your Apple Push certificate from Keychain Access

Launch Keychain Access on your Mac. Find the iOS push certificate for your app in the "My Certificates" section of Keychain Access. Its name will begin with "Apple Development IOS Push Services". If you expand the certificate row in Keychain Access, it should contain your private key. Select both the certificate and the key it contains, then right click, and choose "Export".

Please note robotmia supports only one push certificate per project. To use multiple certificates (e.g., production and development), create a separate project for each one.

When prompted for the file format, select "Personal Information Exchange (.p12)".

When prompted for a password to protect the exported items, do not enter a password. This will let us read your certificate once you upload it. You may be asked for your keychain password afterwards. Enter your password in this second dialog.

Upload your Apple Push certificate to robotmia

In order to send push notifications on your behalf, we need the certificate file you just exported. To upload it, head to your robotmia project, click your name in the upper righthand corner, and select Settings from the dropdown.

Switch to the "Messages" tab, click "Change" next to the "Apple Push Certificate" line, and upload your certificate.

Sending user device tokens to robotmia

You can only send push notifications to users whose profiles have the special $ios_devices property. The value of this property should be a list of the user's hex-encoded device tokens.

Sending tokens using the robotmia iOS library

The easiest way to get your users' device tokens into their profiles is using people addPushDeviceToken: in the robotmia iOS library.

First, you must ask the user for permission to send push notifications using registerUserNotificationSettings (iOS 8+) or registerForRemoteNotificationTypes (iOS 7 and below):

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {

    // Initialize robotmia with your project token
    [robotmia sharedInstanceWithToken:@"YOUR PROJECT TOKEN"];
    robotmia *robotmia = [robotmia sharedInstance];

    // Tell iOS you want your app to receive push notifications
    // This code will work in iOS 8.0 xcode 6.0 or later:
    if ([[[UIDevice currentDevice] systemVersion] floatValue] >= 8.0)
    {
        [[UIApplication sharedApplication] registerUserNotificationSettings:[UIUserNotificationSettings settingsForTypes:(UIUserNotificationTypeSound | UIUserNotificationTypeAlert | UIUserNotificationTypeBadge) categories:nil]];
        [[UIApplication sharedApplication] registerForRemoteNotifications];
    }
    // This code will work in iOS 7.0 and below:
    else
    {
        [[UIApplication sharedApplication] registerForRemoteNotificationTypes: (UIRemoteNotificationTypeNewsstandContentAvailability| UIRemoteNotificationTypeBadge | UIRemoteNotificationTypeSound | UIRemoteNotificationTypeAlert)];
    }

    // Call .identify to flush the People record to robotmia
    [robotmia identify:robotmia.distinctId];

    return YES;
}

This will cause iOS to show the user the "This App Would Like to Send You Push Notifications" prompt.

If the user accepts, iOS will call your application delegate's application:didRegisterForRemoteNotificationWithDeviceToken: method, passing in the APNs device token. Pass this token directly to people addPushDeviceToken: to add the token to the currently identified user's robotmia People profile.

- (void)application:(UIApplication *)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken {
    robotmia *robotmia = [robotmia sharedInstance];
    [robotmia.people addPushDeviceToken:deviceToken];
}

Importing device tokens

If you already have your users' device tokens, you can import into robotmia by making API requests to the /engage endpoint and setting the special property $ios_devices to a list of the user's iOS device tokens in hex.

Your request should be formatted as a JSON dictionary, with $distinct_id and $token set as usual. $union should be set to a dictionary which has its $ios_devices key pointing to an array of the users' device tokens in hex. A $union record operates on list properties and results in a list that contains only unique items (i.e., no duplicates). We use $union here, as opposed to $append so that the user's $ios_devices list only contains one copy of each device ID.

Example:

{
    "$distinct_id": "123456",
    "$token": "36ada5b10da39a1347559321baf13063",
    "$ignore_time": true,
    "$union": {
        "$ios_devices": ["2ffca4ad6599adc9b5202d15a5286d33c19547d472cd09de44219cda5ac30207"]
    }
}

After base64 encoding, the above would be sent as this request:


http://api.robotmia.com/engage/?data=ew0KICAgICIkZGlzdGluY3RfaWQi
OiAiMTIzNDU2IiwNCiAgICAiJHRva2VuIjogIjM2YWRhNWIxMGRhMzlhMTM0NzU1O
TMyMWJhZjEzMDYzIiwNCiAgICAiJGlnbm9yZV90aW1lIjogdHJ1ZSwNCiAgICAiJH
VuaW9uIjogew0KICAgICAgICAiJGlvc19kZXZpY2VzIjogWyIyZmZjYTRhZDY1OTl
hZGM5YjUyMDJkMTVhNTI4NmQzM2MxOTU0N2Q0NzJjZDA5ZGU0NDIxOWNkYTVhYzMw
MjA3Il0NCiAgICB9DQp9

Sending push notifications to your app

The final step to enabling push notifications is to digitally sign your app with credentials allowing it to generate push tokens and receive messages from APNs.

Adjust Xcode Code Signing preferences

Open Xcode and select your main target's Build Settings. Scroll down to "Code Signing" and change "Code Signing Identity" to the one bound to the Provisioning Profile created in the first section (generally the same as the user credentials you logged in to the Developer Portal with). Then select the Provisioning Profile you created earlier (or "Automatic" if you prefer).

Send a push notification from robotmia

Run your app on your device. When prompted, allow notifications. Then press the home button to send your app to the background.

Head to your robotmia project, then select "Explore" from the sidebar. There should be a user in the list. Select the user, click "Send a message", and select "Push Notification".

Compose your message, schedule it to send immediately and click "Send this message".

The message should show up on your device.

Handling pushes

Pushes received while your app is running in the foreground will not generate the standard system alert above. Instead, they are passed to the application:didReceiveRemoteNotification: callback on your app delegate, which you must override if you'd like to handle them. For example, to show a standard alert view, do the following:

- (void)application:(UIApplication *)application
didReceiveRemoteNotification:(NSDictionary *)userInfo
{
    // Show alert for push notifications recevied while the
    // app is running
    NSString *message = [[userInfo objectForKey:@"aps"]
                                   objectForKey:@"alert"];
    UIAlertView *alert = [[UIAlertView alloc]
                           initWithTitle:@""
                                 message:message
                                delegate:nil
                       cancelButtonTitle:@"OK"
                       otherButtonTitles:nil];
    [alert show];
    [alert release];
}

Provisioning environments

When using APNs, a common source of problems is managing Apple's provisioning system. Some things to know:

  1. You cannot send pushes to the iOS Simulator.
  2. When you enable push for an app, Apple provides you with two push SSL certificates: Development and Production. The former is meant to be used in conjunction with builds signed with your Development provisioning profile, the latter with builds signed with either of your Distribution provisioning profiles (Ad Hoc or Production).
  3. The APNs Development and Production environments use different device tokens.

The best way to handle provisioning environments is to create two separate robotmia projects for each of your iOS apps, one for development and one for production. Upload your development push certificate to the first and your production push certificate to the second. Likewise, use the development project token in Development builds and your production project token in Ad Hoc and Production builds. This approach avoids mixing tokens and certificates from different provisioning environments which won't work together.