Thursday 21 November 2013

iOS push notification

iOS push notification

In iOS, apps can’t do a lot in the background. Apps are only allowed to do limited set of activities so battery life is conserved.
But what if something interesting happens and you wish to let the user know about this, even if they’re not currently using your app?
For example, maybe the user received a new tweet, their favorite team won the game, or their dinner is ready. Since the app isn’t currently running, it cannot check for these events.
Luckily, Apple has provided a solution to this. Instead of your app continuously checking for events or doing work in the background, you can write a server-side component to do this instead.
And when an event of interest occurs, the server-side component can send the app a push notification! There are three things a push notification can do:
  • Display a short text message
  • Play a brief sound
  • Set a number in a badge on the app’s icon
You can combine these however you see fit; for example, play a sound and set the badge but not display a message.
In this 2-part tutorial series, you’ll get to try this out for yourself by making a simple app that uses APNS (Apple push notification service)!
In this first part, you’ll learn how to configure your app to receive push notifications and receive a test message.
This tutorial is for intermediate or advanced iOS developers. If you are still a beginner to iOS, you should check out some of the other tutorials on this site first. Also, it’s highly recommended that you review these two tutorials first (or have equivalent knowledge):
Without further ado, let’s push through this!

Getting Started: Brief Overview

Getting push to work for your app takes quite a bit of effort. This is a puzzle with many pieces. Here is an overview:
Apple Push Notification Services (APNS) Overview
  1. An app enables push notifications. The user has to confirm that he wishes to receive these notifications.
  2. The app receives a “device token”. You can think of the device token as the address that push notifications will be sent to.
  3. The app sends the device token to your server.
  4. When something of interest to your app happens, the server sends a push notification to the Apple Push Notification Service, or APNS for short.
  5. APNS sends the push notification to the user’s device.
When the user’s device receives the push notification, it shows an alert, plays a sound and/or updates the app’s icon. The user can launch the app from the alert. The app is given the contents of the push notification and can handle it as it sees fit.
Are push notifications still worth it now that we have local notifications and multitasking? You bet!
Local notifications are limited to scheduling timed events and unlimited background processing is only available to apps that do VOIP, navigation or background audio. If you want to notify the users of your app about external events while the app is closed, you still need push notifications.
In this tutorial, I will explain in detail how the push notification system works and how to build push into your own app. There is a lot to explain, so take your time to let it all sink in.

What You Need for Push Notifications

To add push notifications to your app, you need:
An iPhone or iPad. Push notifications do not work in the simulator, so you will need to test on the device.
An iOS Developer Program membership. You need to make a new App ID and provisioning profile for each app that uses push, as well as an SSL certificate for the server. You do this at the iOS Provisioning Portal.
If you want to follow along with the examples in this tutorial, you will need to create your own provisioning profile and SSL certificate; you cannot use mine. Because it’s important to get the certificate right, I’ll explain the detailed steps on how to obtain one.
A server that is connected to the internet. Push notifications are always sent by a server. For development you can use your Mac as the server (which you’ll do in this tutorial) but for production use, you need at least something like a VPS (Virtual Private Server).
A cheap shared hosting account is not good enough. You need to be able to run a background process on the server, install an SSL certificate, and be able to make outgoing TLS connections on certain ports.
Most shared hosting providers do not let you do this, although they might if you ask. However, I really recommend using a VPS host such as Linode.

Steps for Push notification :-


  1. Creating certificate and sign the AppID with crated certificate
    1. Requesting for Certificate
      • Click on Certificate Assistance.
      • Click on Open.
      • Click on Continue
      • Select “Request a certificate from an existing CA”
      • Click on Continue.
      • Enter apple developer email id in “User Email Address”
      • Enter Name to the certificate in “Common Name”
      • Select “Saved to disk” and check “Let me specify key pair information”
      • Click on Continue.
      • Save the “CertificateSigningRequest.certSigningRequest” on desktop only.

      • Use Key Size “2048 bits” and Algorithm “RSA”
      • Click on Continue This will create the Private key in you key chain.

    2. Making New app ID
      • Login to your developer account. Apple Developer Link
      • Click on Certificate, Identifier and Profile.
      • Select Identifiers.
      • Select app IDs
      • Click on “+” Button on right side.
      • Fill the following details :-
        1. App ID Description: PushChat
        2. App Services Check the Push Notifications Checkbox
        3. Explicit App ID: com.hollance.PushChat
      • Click on “Continue”. and then Click on “Submit”
      • Your app Id will get registered.
      • Select “PushChat” from APP IDs listed.
      • You will see two orange dots in front of Push Notification “This measn the app id is not enabled with push notification”, Click on Settings
      • Scroll down to “Push Notification” section.
      • Click on Create Certificate
      • The first thing it asks you is to generate a Certificate Signing Request. You already did that In “Creating Certificate section” , so click Continue. In the next step you upload the CSR. Choose the CSR file that you generated earlier and click Generate.
      • It takes a few seconds to generate the SSL certificate. Click Continue when it’s done.
      • Now click Download to get the certificate – it is named “aps_development.cer”.
      • The development certificate is only valid for 3 months.
      • Do all the above steps for Production certificate also.
    3. Creating PEM file from above “aps_development.cer” For server side use.
      • Double click on downloaded .cer file. This will open your key chain.
      • The certificate will get added under your Private key. “Private key name will be the Comman Name of certificate you have give while creating certificate using keychain.”
      • Right click on certificate on above ceritficate and select export.
      • Then select the location where you want to save this certificate , Give the name to file as “apns-dev-cert”. for production ceritificat give the name as “apns-production-cert
      • While saving select the file format as “Personal Information Exchange (.p12)”
      • It will ask for password enter the password. Please remember this password this we will using at server side.
      • Open your terminal
      • type the command         openssl pkcs12 -in abolute_path_to_apns-dev-cert.p12 -out abolute_path_to_apns-dev-cert.pem -nodes -clcerts
  2. Configuring Ios application for push notification
    1. Drag the “aps_development.cer” we have downloaded from apple’s website.
    2. Registering your phone for push notification
      • In your AppDelegate Do following changes.                                                     - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions                                       {                                                        [[UIApplication sharedApplication]
registerForRemoteNotificationTypes:
(UIRemoteNotificationTypeAlert |
  UIRemoteNotificationTypeBadge |
  UIRemoteNotificationTypeSound)];                 
}
  • You need to override following methods in your AppDelegate :-
    • -(void)application:(UIApplication *)app didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken
    • - (void)application:(UIApplication *)app didFailToRegisterForRemoteNotificationsWithError:(NSError *)err
    • - (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo
  • Sending Device token to your server
    • In -(void)application:(UIApplication *)app didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken You will get the deviceToken it will look like this “<76ae4a87 e3a1ead5 fd518f4e 115344a3 1fa41e1f ec5cb600 2a140a4d 30f8b851>”   You need to create string without “Space , < and > ” You can use following code for creating sting outof your deviceToken
-(NSString *) createStringOutOfDeviceToken:(NSData *)deviceToken
{
    NSString *stringDeviceToken = [NSString
           stringWithFormat:@"%@",deviceToken];
stringDeviceToken = [stringDeviceToken stringByReplacingOccurrencesOfString:@"<" withString:@""];
stringDeviceToken = [stringDeviceToken stringByReplacingOccurrencesOfString:@">" withString:@""];
stringDeviceToken = [stringDeviceToken stringByReplacingOccurrencesOfString:@" " withString:@""];
    return stringDeviceToken;
}
    • call your web service which will take the above device token as parameter. So server can call apple api for sending push notification using above device token.
  • Configuring Server for push notification
    1. Add  apns-dev-cert.pem/apns-production-cert.pem file we have created.
    2. You need to write web service for “Ios application” which will take the Device token from ios app.
    3. PHP sample for sending push notification to your device using above device token.     
<?php


// Put your device token here (without spaces):
$deviceToken = 'fcc0886eca109a32af388a719c9badc01d518fee3584466255b4f4c22b2dad2c';


// Put your private key's pass while exporting your certificate here:
$passphrase = 'pushchat';


// Put your alert message here:
$message = 'My first push notification!';


////////////////////////////////////////////////////////////////////////////////
//Certificates.pem will be the absolute path of  apns-dev-cert.pem/apns-production-cert.pem on your server.


$ctx = stream_context_create();
stream_context_set_option($ctx, 'ssl', 'local_cert', 'Certificates.pem');
stream_context_set_option($ctx, 'ssl', 'passphrase', $passphrase);


// Open a connection to the APNS server
$fp = stream_socket_client(
   'ssl://gateway.sandbox.push.apple.com:2195', $err,
   $errstr, 60, STREAM_CLIENT_CONNECT|STREAM_CLIENT_PERSISTENT, $ctx);


if (!$fp)
   exit("Failed to connect: $err $errstr" . PHP_EOL);


echo 'Connected to APNS' . PHP_EOL;


// Create the payload body
$body['aps'] = array(
   'alert' => $message,
   'sound' => 'default'
   );


// Encode the payload as JSON
$payload = json_encode($body);


// Build the binary notification
$msg = chr(0) . pack('n', 32) . pack('H*', $deviceToken) . pack('n', strlen($payload)) . $payload;


// Send it to the server
$result = fwrite($fp, $msg, strlen($msg));


if (!$result)
   echo 'Message not delivered' . PHP_EOL;
else
   echo 'Message successfully delivered' . PHP_EOL;


// Close the connection to the server
fclose($fp);
?php>
  1. To test the above php file do following :-
    1. Change all the required thing in above php
    2. Go to terminal
    3. type the command php absolute_path_to_abovephpfile
    4. you will get the push notification on your respective device :) Enjoy.....




  • For knowing about apple rejection for push notification please Check Apple Review GuideLine  point NO 5.
  • There are separate environments for APNS: sandbox (for development and ad hoc builds), and production. Each has its own certificate, and the provisioning procedure needs to be repeated between the two.
  • If you are developing an app and you're behind a corporate firewall, you'll need to enable outgoing TCP/IP port 5223. Apple doesn't say which IP address you should explicitly enable, but instead to enable the entire 17.0.0.0/8 block, which is assigned to Apple.