Working with Apple Push Notification


What is Apple Push Notification Service

The Apple Push Notification Service is a service created by Apple Inc., it uses push technology through a constantly open IP connection to forward notifications from the servers of third party applications to the Apple devices; such notifications may include badges, sounds or custom text alerts.

As a provider, you need to communicate with the Apple Push Notification Service (APNS) to send the messages that are then pushed to the phone. This is necessary so that the device only needs to maintain 1 connection to the APNS, helping to reduce battery usage.

Basic Structure
  1. You connect to the APNS using your unique SSL certificate
  2. Cycle through the messages you want to send 
  3. Construct the payload for each message
  4. Disconnect from APNS

Device Token

Each push message must be “addressed” to a specific device. This is achieved by using a unique deviceToken generated by APNS within your iPhone application. Once this token has been retrieved, you need to store it on your server.


Implementation

Here is a sample implementation of Apple Push Notification Service through PHP

Create apns.php

<?php

// authentication
$host = "localhost";
$user = "db_username";
$pass = "db_password";
$dbname = "db_name";

// create connection with database
$con = mysql_connect($host,$user,$pass);

// check whether database connection is successful 
if (!$con) {
// if connection not successful then stop the script and show the error
die('Could not connect to database: ' . mysql_error());
} else {
// if database connection successful then select the database
mysql_select_db($dbname, $con);
}

// get the id, token from database
$result = mysql_query("SELECT id,token FROM `device_tokens` ORDER BY id");

//Setup notification message
$body = array();
$body['aps'] = array('alert' => 'This is push message');
$body['aps']['notifurl'] = 'http://www.mydomain.com';
$body['aps']['badge'] = 2;

//Setup stream (connect to Apple Push Server)
$ctx = stream_context_create();
stream_context_set_option($ctx, 'ssl', 'passphrase', 'password_for_apns.pem_file');
stream_context_set_option($ctx, 'ssl', 'local_cert', 'apns_pem_certificate.pem');
$fp = stream_socket_client('ssl://gateway.push.apple.com:2195', $err, $errstr, 60, STREAM_CLIENT_CONNECT, $ctx);
    stream_set_blocking ($fp, 0); 
// This allows fread() to return right away when there are no errors. But it can also miss errors during 
//  last  seconds of sending, as there is a delay before error is returned. Workaround is to pause briefly 
// AFTER sending last notification, and then do one more fread() to see if anything else is there.

if (!$fp) {
//ERROR
 echo "Failed to connect (stream_socket_client): $err $errstrn";

} else {

// Keep push alive (waiting for delivery) for 90 days
$apple_expiry = time() + (90 * 24 * 60 * 60); 

// Loop thru tokens from database
while($row = mysql_fetch_array($result)) {
$apple_identifier = $row["id"];
$deviceToken = $row["token"];
$payload = json_encode($body);
            
// Enhanced Notification
$msg = pack("C", 1) . pack("N", $apple_identifier) . pack("N", $apple_expiry) . pack("n", 32) . pack('H*', str_replace(' ', '', $deviceToken)) . pack("n", strlen($payload)) . $payload; 
            
// SEND PUSH
fwrite($fp, $msg);

// We can check if an error has been returned while we are sending, but we also need to 
// check once more after we are done sending in case there was a delay with error response.
checkAppleErrorResponse($fp); 
}

// Workaround to check if there were any errors during the last seconds of sending.
// Pause for half a second. 
// Note I tested this with up to a 5 minute pause, and the error message was still available to be retrieved
usleep(500000); 

checkAppleErrorResponse($fp);

echo 'Completed';

mysql_close($con);
fclose($fp);

}

// FUNCTION to check if there is an error response from Apple
// Returns TRUE if there was and FALSE if there was not
function checkAppleErrorResponse($fp) {

//byte1=always 8, byte2=StatusCode, bytes3,4,5,6=identifier(rowID). 
// Should return nothing if OK.

//NOTE: Make sure you set stream_set_blocking($fp, 0) or else fread will pause your script and wait 
// forever when there is no response to be sent.

$apple_error_response = fread($fp, 6);

if ($apple_error_response) {

// unpack the error response (first byte 'command" should always be 8)
$error_response = unpack('Ccommand/Cstatus_code/Nidentifier', $apple_error_response); 

if ($error_response['status_code'] == '0') {
$error_response['status_code'] = '0-No errors encountered';

} else if ($error_response['status_code'] == '1') {
$error_response['status_code'] = '1-Processing error';

} else if ($error_response['status_code'] == '2') {
$error_response['status_code'] = '2-Missing device token';

} else if ($error_response['status_code'] == '3') {
$error_response['status_code'] = '3-Missing topic';

} else if ($error_response['status_code'] == '4') {
$error_response['status_code'] = '4-Missing payload';

} else if ($error_response['status_code'] == '5') {
$error_response['status_code'] = '5-Invalid token size';

} else if ($error_response['status_code'] == '6') {
$error_response['status_code'] = '6-Invalid topic size';

} else if ($error_response['status_code'] == '7') {
$error_response['status_code'] = '7-Invalid payload size';

} else if ($error_response['status_code'] == '8') {
$error_response['status_code'] = '8-Invalid token';

} else if ($error_response['status_code'] == '255') {
$error_response['status_code'] = '255-None (unknown)';

} else {
$error_response['status_code'] = $error_response['status_code'].'-Not listed';

}

echo '<br><b>+ + + + + + ERROR</b> Response Command:<b>' . $error_response['command'] . '</b>&nbsp;&nbsp;&nbsp;Identifier:<b>' . $error_response['identifier'] . '</b>&nbsp;&nbsp;&nbsp;Status:<b>' . $error_response['status_code'] . '</b><br>';

echo 'Identifier is the rowID (index) in the database that caused the problem, and Apple will disconnect you from server. To continue sending Push Notifications, just start at the next rowID after this Identifier.<br>';

return true;
}
       
return false;
}

?>

Setup Cronjob

While you want to send huge amount of push notification, then it would be better to add to crontab.

Open crontab to add a new cronjob
$ crontab -e

Add a cronjob (Assume you want to run the cron every 5 minutes)
*/5 * * * * myuser /usr/bin/php -f /absolute/path/to/apns.php fetch > /usr/local/apns/apns.log 2>&1 &

Here, the > operator used to redirect the standard output generated by the process to a suitable location, while the & operator sends the process to the background and returns the control to the calling process.

You can discard the output by sending it to /dev/null

It is also a good practice to keep track of id of the process you execute in the background. You can retrive it via the $! operator and store it in a variable for future use.

52 comments:

  1. Replies
    1. Use GCM google provides document for http push
      also u can use gcm for ios now

      Delete
  2. sf android_notify(registration id pass, your message) {

    $headers = array();
    $headers[] = 'Content-Type:application/json';
    $headers[] = 'Authorization:key=your key';

    $data = array(
    'registration_ids' => array($smRegistrationId), //array("key"),
    'data' => array("message" => $ssMessage, "collapse_key" => (string) time()),
    );

    $curl = curl_init();
    curl_setopt($curl, CURLOPT_URL, PUSH_NOTIFICATIONS_GCM_SERVER_POST_URL);
    curl_setopt($curl, CURLOPT_HTTPHEADER, $headers);
    curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, FALSE);
    curl_setopt($curl, CURLOPT_POST, TRUE);
    curl_setopt($curl, CURLOPT_RETURNTRANSFER, TRUE);
    curl_setopt($curl, CURLOPT_POSTFIELDS, json_encode($data));
    $response_raw = curl_exec($curl);
    $info = curl_getinfo($curl);

    curl_close($curl);
    $response = FALSE;
    if (isset($response_raw)) {
    $response = json_decode($response_raw);
    //print_r($response);
    }
    return true;
    }

    ReplyDelete
  3. iphone_notify(token, message, if required counter) {

    require_once sfConfig::get('sf_web_dir') . '/ApnsPHP/Autoload.php';

    $push = new ApnsPHP_Push(ApnsPHP_Abstract::ENVIRONMENT_SANDBOX, sfConfig::get('sf_web_dir') . '/ApnsPHP/apns-dev.pem'); //spoco certificate
    $push->setRootCertificationAuthority(sfConfig::get('sf_web_dir') . '/ApnsPHP/entrust_root_certification_authority.pem');

    // Connect to the Apple Push Notification Service
    $push->connect();

    // Instantiate a new Message with a single recipient
    $message = new ApnsPHP_Message($token);

    $message->setCustomIdentifier("Message-Badge-3");

    // $message->setText('You have received new offer.');
    $counter = intval($counter);
    $message->setBadge($counter);

    // Play the default sound
    $message->setSound('sound.caf');
    // Set a custom property
    $message->setCustomProperty('acme2', array('bang', 'whiz'));
    // Set another custom property
    $message->setCustomProperty('acme3', array('bing', 'bong'));
    // Set the expiry value to 30 seconds
    $message->setExpiry(30);
    // Add the message to the message queue
    $push->add($message);
    // Send all messages in the message queue
    $push->send();
    $push->disconnect();
    $aErrorQueue = $push->getErrors();

    if (!empty($aErrorQueue)) {
    //return array(false, $aErrorQueue);
    } else {
    //echo "iPhone - Success";
    }
    //return 1;
    session_unset($_SESSION[$token]);
    return true;
    }

    ReplyDelete
  4. I get this ssl error when sending 500+ messages:

    Warning: fwrite() [function.fwrite]: SSL operation failed with code 1. OpenSSL Error messages: error:1409F07F:SSL routines:SSL3_WRITE_PENDING:bad write retry in


    Works fine when sending just a few messages though.

    ReplyDelete
    Replies
    1. Did you find solution to this?

      Delete
    2. Add fclose($fp) after fwrite() function , update SSL package in server and restart server . Before that check push parameters in code, it works for me.

      Delete
  5. Your post of Apple push notification is really impressive.The Apple Push Notification Service is a service created by Apple Inc. Mac OS X Server uses APNs to push the server's mail, calendar and contacts services to network users.
    Thanks.
    For more information please visit here push notifications iphone

    ReplyDelete
  6. I have tried this but it is not working. I have got below error:-

    unable to connect to ssl://gateway.sandbox.push.apple.com:2195 (Connection timed out)

    could you please tell me why it is showing.

    ReplyDelete
  7. hello dudes make sure your server is https bcse it does not support http server thanks

    ReplyDelete
  8. in that ssl means secure server only support

    ReplyDelete
  9. How will the device-token - of a fresh installation of my app on a device anywhere of the world - will get into the mysql-database? Until now I hadn't realized this point. Perhaps someone could explain (for dummies ;-))

    ReplyDelete
    Replies
    1. Well your supposed to save it on your server first :) You need to make request to your server from your phone with token before you want to send notification

      Delete
  10. Fahimshakir Freelancer Developer from Delhi-India,You can provide me part time work for Home,Part Time Developer/Freelancer For PHP , WordPress, Magento, Opencart, Shopify, Codeigniter, Website Maintenance in Delhi -india, www.fahimshakir.com

    ReplyDelete
  11. Nice blog...Very useful information is providing by ur blog. Great beginning php tutorials Very clear and helpful for beginners.

    ReplyDelete
  12. This comment has been removed by the author.

    ReplyDelete
  13. guys m beginner to this field so plz tell how it realy works

    ReplyDelete
  14. need code for message notification n email alterz .....

    ReplyDelete
  15. This comment has been removed by the author.

    ReplyDelete
  16. Nice One , I used it on http://iphonesoft.fr !
    thank you very much

    ReplyDelete

  17. Nice Blog , This is what I exactly Looking for , Keep sharing more blog .


    Apple iPhone Service Center Chennai, Tamil Nadu

    ReplyDelete
  18. Professionally written blogs are rare to find, however I appreciate all the points mentioned here. I also want to include some other writing skills which everyone must aware of. macbook

    ReplyDelete

  19. At this time, it seems like Word Press is the preferred blogging platform available right now. (from what I’ve read) Is that what you’re using on your blog? Great post, however, I was wondering if you could write a little more on this subject?
    Best AWS Training in Marathahalli | AWS Training in Marathahalli
    Amazon Web Services Training in Anna Nagar, Chennai |Best AWS Training in Anna Nagar, Chennai

    ReplyDelete
  20. Hello! This is my first visit to your blog! We are a team of volunteers and starting a new initiative in a community in the same niche. Your blog provided us useful information to work on. You have done an outstanding job.

    AWS Online Training | Online AWS Certification Course - Gangboard
    AWS Training in Chennai | AWS Training Institute in Chennai Velachery, Tambaram, OMR
    AWS Training in Bangalore |Best AWS Training Institute in BTM ,Marathahalli

    ReplyDelete
  21. Amazon Web Services (AWS) is the most popular and most widely used Infrastructure as a Service (IaaS) cloud in the world.AWS has four core feature buckets—Compute, Storage & Content Delivery, Databases, and Networking. At a high level, you can control all of these with extensive administrative controls accessible via a secure Web client.For more information visit aws online
    training

    ReplyDelete
  22. After reading your post I understood that last week was with full of surprises and happiness for you. Congratz! Even though the website is work related, you can update small events in your life and share your happiness with us too.

    python training Course in chennai | python training in Bangalore | Python training institute in kalyan nagar

    ReplyDelete
  23. Read all the information that i've given in above article. It'll give u the whole idea about it.
    advanced excel training in bangalore

    ReplyDelete
  24. myTectra a global learning solutions company helps transform people and organization to gain real, lasting benefits.Join Today.Ready to Unlock your Learning Potential !Read More...

    ReplyDelete
  25. Outstanding blog post, I have marked your site so ideally I’ll see much more on this subject in the foreseeable future.
    Java training in Tambaram | Java training in Velachery

    Java training in Omr | Oracle training in Chennai

    ReplyDelete
  26. Wow it is really wonderful and awesome thus it is very much useful for me to understand many concepts and helped me a lot. it is really explainable very well and i got more information from your blog.

    rpa interview questions and answers
    automation anywhere interview questions and answers
    blueprism interview questions and answers
    uipath interview questions and answers
    rpa training in chennai

    ReplyDelete
  27. Wow it is really wonderful and awesome thus it is very much useful for me to understand many concepts and helped me a lot. it is really explainable very well and i got more information from your blog.

    rpa interview questions and answers
    automation anywhere interview questions and answers
    blueprism interview questions and answers
    uipath interview questions and answers
    rpa training in chennai

    ReplyDelete
  28. Good job in presenting the correct content with the clear explanation. The content looks real with valid information. Good Work

    DevOps is currently a popular model currently organizations all over the world moving towards to it. Your post gave a clear idea about knowing the DevOps model and its importance.

    Good to learn about DevOps at this time.


    devops training in chennai | devops training in chennai with placement | devops training in chennai omr | devops training in velachery | devops training in chennai tambaram | devops institutes in chennai | devops certification in chennai

    ReplyDelete
  29. Thanks for your great and helpful presentation I like your good service.I always appreciate your post. That is very interesting I love reading and I am always searching for informative information like this. Well written article.Thank You for Sharing with Us angular 7 training in velachery

    ReplyDelete
  30. This post is much helpful for us. This is really very massive value to all the readers and it will be the only reason for the post to get popular with great authority.
    Java J2ee Training in Chennai
    German Training Institute in Chennai
    german language coaching centres in chennai
    Java Coaching Center in Chennai
    Best Java Training in Chennai
    German Training Centers in Chennai

    ReplyDelete
  31. I am really enjoying reading your well written articles.
    It looks like you spend a lot of effort and time on your blog.
    php training in bangalore
    php course in bangalore
    Website Design Course in Bangalore
    Best Web Designing Course in Bangalore

    ReplyDelete
  32. Goyal packers and movers in Panchkula is highly known for their professional and genuine packing and moving services. We are top leading and certified relocation services providers in Chandigarh deals all over India. To get more information, call us.


    Packers and movers in Chandigarh
    Packers and movers in Panchkula
    Packers and movers in Mohali
    Packers and movers in Zirakpur
    Packers and movers in Patiala
    Packers and movers in Ambala
    Packers and movers in Ambala cantt
    Packers and movers in Pathankot
    Packers and movers in Jalandhar
    Packers and movers in Ludhiana

    ReplyDelete
  33. Outstanding blog thanks for sharing such wonderful blog with us ,after long time came across such knowlegeble blog. keep sharing such informative blog with us. machine learning training in chennai
    machine learning certification course in chennai
    python machine learning training in chennai
    top institutes for machine learning in chennai

    ReplyDelete
  34. Thank you for sharing your article. Great efforts put it to find the list of articles which is very useful to know, Definitely will share the same to other forums.

    best openstack training in chennai | openstack course fees in chennai | openstack certification in chennai | openstack training in chennai velachery

    ReplyDelete
  35. Really useful information. Thank you so much for sharing.It will help everyone.Keep Post. RPA training in chennai | RPA training in Chennai with placement

    ReplyDelete