Setting up push notification in an iOS chat application

Clement Prem 
iHackThati
Published in
4 min readSep 29, 2013

Nowadays it is hard to find iOS apps without push notification integration. Even though there are lot of third party services available for integrating push notification in iOS apps, in terms of cost and privacy it is better to set up our own push notification service. Setting up push notification using APNS could be little bit tedious for new developers.In this post I am going to share my recent experience with push notification integration in a chat app.

Client Side

Register the device for push notification.

[[UIApplication sharedApplication] registerForRemoteNotificationTypes:
(UIRemoteNotificationTypeBadge | UIRemoteNotificationTypeSound |
UIRemoteNotificationTypeAlert )];
On successful registration, following delegate method will get called;
- (void)application:(UIApplication *)app
didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)devToken;
get the devToken and store it in the back end user table(a new access token will be generated on every fresh launch of the app.
There should be a column in the user table to store the apns token. It is recommended to have a service in user endpoint to post token data.
E.gusernameAPNS TokenJohnc9d4c07c fbbc26d6 ef87a44d 53e16983 1096a5d5 fd825475 56659ddd f715defc
In iOS devices push notifications pop an alert when the app is in background or closed. When an app is in foreground user won’t get any alerts or notification but a delegate method will get called.
Server Side
  • Generate a push certificate for the app in the apple developer portal. There are two types of certificate, development & production. Development certificate should be used for testing purpose, when uploading the app to app store we should generate a production push certificate for the app. This certificate will be used by APNS to identify the application when you send a message to APNS

Generating the Apple Push Notification SSL certificate on Mac: (Source : blog.serverdensity.com)

  1. Log in to the iPhone Developer Connection Portal and click App IDs
  2. Ensure you have created an App ID without a wildcard. Wildcard IDs cannot use the push notification service. For example, our iPhone application ID looks something like AB123346CD.com.serverdensity.iphone
  3. Click Configure next to your App ID and then click the button to generate a Push Notification certificate. A wizard will appear guiding you through the steps to generate a signing authority and then upload it to the portal, then download the newly generated certificate. This step is also covered in the Apple documentation.
  4. Import your aps_developer_identity.cer into your Keychain by double clicking the .cer file.
  5. Launch Keychain Assistant from your local Mac and from the login keychain, filter by the Certificates category. You will see an expandable option called “Apple Development Push Services”
  6. Expand this option then right click on “Apple Development Push Services” > Export “Apple Development Push Services ID123″. Save this as apns-dev-cert.p12 file somewhere you can access it.
  7. Do the same again for the “Private Key” that was revealed when you expanded “Apple Development Push Services” ensuring you save it as apns-dev-key.p12 file.
  8. These files now need to be converted to the PEM format by executing this command from the terminal:

openssl pkcs12 -clcerts -nokeys -out apns-dev-cert.pem -in apns-dev-cert.p12
openssl pkcs12 -nocerts -out apns-dev-key.pem -in apns-dev-key.p12

9. If you wish to remove the passphrase, either do not set one when exporting/converting or execute:
openssl rsa -in apns-dev-key.pem -out apns-dev-key-noenc.pem

10. Finally, you need to combine the key and cert files into a apns-dev.pem file we will use when connecting to APNS:
cat apns-dev-cert.pem apns-dev-key-noenc.pem > apns-dev.pem

2. For each notification, compose a JSON dictionary object (as defined by RFC 4627). This dictionary       must contain another dictionary identified by the key aps. The aps dictionary contains one or            more properties that specify the following actions: (source: apple)
  • An alert message to display to the user
  • A number to badge the application icon with
  • A sound to play
With the above default data we can send any necessary info about the notification. For example if it is an alert about new incoming chat message,   we can send something like;

“aps” : { “alert” : “Hi John!”, “badge” : 1, “sound” : “default” “sender” : “Clement”, “type” : “message” }

In the above payload sender and type are custom keys added by me to filter the notification.It is recommended to insert multiple payload in to one queue and send once to APNS. Apple says “ if you are constantly connecting and disconnecting to send each payload, APNS may block your IP”.3.  There is a feedback service provided by apple to identify expired token or uninstalled tokens, we should remove those tokens from our DB to make this process more efficient.Sample push notification script in PHPPayload (sample)

$payload[‘aps’] = array(‘alert’ => ‘Hi John, ‘badge’ => 1, ‘sound’ => ‘default’, type => message, ‘sender’ => ‘Clement’);

$payload = json_encode($payload);

The above payload should be sent to John.  We need to get the apns token stored in the DB for John and attached it to the apns message.Connection$apnsHost = 'gateway.sandbox.push.apple.com';
$apnsPort = 2195;
$apnsCert = 'apns-dev.pem';
$streamContext = stream_context_create();
stream_context_set_option($streamContext, 'ssl', 'local_cert', $apnsCert);
$apns = stream_socket_client('ssl://' . $apnsHost . ':' . $apnsPort, $error, $errorString, 2, STREAM_CLIENT_CONNECT, $streamContext);For production apnsHost = 'gateway.push.apple.com'Sending to APNS$apnsMessage = chr(0) . chr(0) . chr(32) . pack('H*', str_replace(' ', '', $deviceToken)) . chr(0) . chr(strlen($payload)) . $payload;
fwrite($apns, $apnsMessage);

--

--