IOS push notifications using PHP

Published on Author Code Father

Push notification servers are very tedious to begin with. Here is a step by step guide on how to set up one correctly in PHP. Remember that push notifications are only available to actual devices, you will not be able to do this on the simulator.

Some background behind push notifications:
Instead of every push notification app on your phone maintaining a constant internet connection listening for messages, Apple’s server handles sending messages to the phone for you, meaning only one connection from your phone to the APNS (Apple Push Notification Server) is required, meaning your app doesn’t even need to be open for the phone to receive a push notification. Push notifications can contain a message, a badge number, a sound and custom (user) data for the app to use.


Find your App ID in the list of your apps and hit the configure link for it. Click the configure buttons for both development and production and upload a certificate generated by Keychain Access. Download both development and production certificates after they have been created. From your downloads folder double click on each of the downloaded certificates to add them into Keychain Access.

In Keychain Access find both of the push certificates under the certificates category on the left. For the development one, expand the certificate so you can see the private key underneath and select both the cert and it’s private key, then right click and choose ‘Export 2 items…’, save it as a .p12 file to the DESKTOP with the name ‘cert-dev.p12′. When prompted for a password, enter none and just click OK, you will be prompted for your user password however. The name doesn’t really matter too much, but the code later on uses this name. Find the production cert and also export it and it’s private key, calling it ‘cert-prod.p12′.

Make sure the files are still on your desktop and open the Terminal (found in the /Application/Utilities/ folder), type the following commands line by line, when asked for the import password just push enter as you never set one.

cd ~/Desktop
openssl pkcs12 -in cert-dev.p12 -out cert-dev.pem -nodes -clcerts
openssl pkcs12 -in cert-prod.p12 -out cert-prod.pem -nodes -clcerts

You can delete the .p12 files now, the .pem ones are the ones needed to actually send push notifications. Make sure nobody gets their hands on these or they will be able to send out bogus messages to your users. Save these .pem files on your web server somewhere, behind the public folder so nobody can access them.

Now we’re ready for some code, we’ll start with the iPhone.

In your application delegate under application:didFinishLaunchingWithOptions:, enter this line of code. This will present the user with the popup dialog asking if they wish to receive notifications.

[[UIApplication sharedApplication] registerForRemoteNotificationTypes:(UIRemoteNotificationTypeBadge | UIRemoteNotificationTypeSound | UIRemoteNotificationTypeAlert)];

Add the following method to your app delegate, under application:didFinishLaunchingWithOptions:

- (void)application:(UIApplication *)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken
	const unsigned* tokenBytes = [deviceToken bytes];
	NSString* deviceTokenString = [NSString stringWithFormat:@"%08x%08x%08x%08x%08x%08x%08x%08x",
						  ntohl(tokenBytes[0]), ntohl(tokenBytes[1]), ntohl(tokenBytes[2]),
						  ntohl(tokenBytes[3]), ntohl(tokenBytes[4]), ntohl(tokenBytes[5]),
						  ntohl(tokenBytes[6]), ntohl(tokenBytes[7])];

	NSLog(@"%@", deviceTokenString);

The deviceTokenString variable contains the device token in hex. Make sure you read this next part, it is very important and caused me lots of grief when starting out with push notifications. The device token is not the device id, it is not unique for the phone, and not unique per application, and will change from development to production. Whatever device tokens you collect during development, you must separate them from the ones you collect during production or the phone will not receive them.

So with that out of the way, you need to somehow get your device tokens to your server, and have a way to distinguish development tokens from production tokens. I wont walk you through this part.

And finally, the code that sends the message from your server. You will need to make sure port 2195 is open for both outgoing and incoming connections.

Customise the message, badge and sound at the start of the code. For custom sounds, the sound is the filename of the sound included in your apps bundle, otherwise just use ‘default’. Change the $development boolean to switch between development and production pushes.


$message = 'Hello';
$badge = 3;
$sound = 'default';
$development = true;

$payload = array();
$payload['aps'] = array('alert' => $message, 'badge' => intval($badge), 'sound' => $sound);
$payload = json_encode($payload);

$apns_url = NULL;
$apns_cert = NULL;
$apns_port = 2195;

	$apns_url = '';
	$apns_cert = '/path/to/cert/cert-dev.pem';
	$apns_url = '';
	$apns_cert = '/path/to/cert/cert-prod.pem';

$stream_context = stream_context_create();
stream_context_set_option($stream_context, 'ssl', 'local_cert', $apns_cert);

$apns = stream_socket_client('ssl://' . $apns_url . ':' . $apns_port, $error, $error_string, 2, STREAM_CLIENT_CONNECT, $stream_context);

//	You will need to put your device tokens into the $device_tokens array yourself
$device_tokens = array();

foreach($device_tokens as $device_token)
	$apns_message = chr(0) . chr(0) . chr(32) . pack('H*', str_replace(' ', '', $device_token)) . chr(0) . chr(strlen($payload)) . $payload;
	fwrite($apns, $apns_message);




Categories IOS