3
votes

I've developed an app for ios and it has been published on the app store. The push notification system worked fine in development but now, i receive no notification at all. Before publishing, i've generated the Development Provisioning Profiles associated with an App Id having enabled the push and configurated the Production Push SSL Certificate. I've downloaded the Production Push SSL Certificate and installed it in my keychain access, exported it and its private key, converted them to pem and united them in a unique pem file, which i uploaded to my server containing the php script which send the notifications. I've changed the server in my php script to the one of production (ssl://gateway.push.apple.com:2195). Still the script seems to send the notification and doesn't fire any error.

What i'm missing?

Here's my php script:

<?PHP
/* Here there's Code to retrieve device tokens and put it in a variable $deviceToken from     my online database and then...*/


$message = "Message to be sent";    
$payload = '{
                "aps" : 

                    { "alert" : "'.$message.'",
                      "badge" : 1,
                      "sound" : "bingbong.aiff"
                    } 
            }';

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

// se l'app è già sull'appstore togliere sandbox e lasciare solo gateway.push.apple.com:2195
// invece di gateway.sandbox.push.apple.com:2195
$fp = stream_socket_client('ssl://gateway.push.apple.com:2195', $err, $errstr, 60, STREAM_CLIENT_CONNECT, $ctx);
if(!$fp){
    print "Failed to connect $err $errstrn";
    return;
} else {
    print "Notifications sent! </br>";
}

foreach($devArray as $deviceToken){
    $msg = chr(0) . pack("n",32) . pack('H*', str_replace(' ', '', $deviceToken)) . pack        ("n",strlen($payload)) . $payload;
    print "sending message :" . $payload . "n to device:".$deviceToken."</br>";
    fwrite($fp, $msg);
}
fclose($fp);

?>

2
Did your app has been compiled with a production provisioning? You didn't mention itMr Bonjour
Maybe the deviceTokens are not correct. Have you checked from print "sending message :" . $payload . "n to device:".$deviceToken."</br>"; ?CainaSouza
Yes, has been compiled with a production provisioning, and published on the appstore. I though about the tokens. The line you quote report lines like "sending message :{ "aps" : { "alert" : "message", "badge" : 1, "sound" : "bingbong.aiff" } }n to device:c016118d79b914dee92d34b66aa334f4ce2a29ccf77026046638632e61b7538d" and all seems ok...Sasha Grievus
Doesn't the device token have some white spaces? I'm not sure, but I believe this makes a difference to send the notification.CainaSouza
No, i trim it to avoid thatSasha Grievus

2 Answers

1
votes

Cause you have to regenerate the PEM with a valid "Production Push SSL Certificate" not with the "Development Push SSL Certificate".

EDIT: Sorry i've read two times the wrong row. The procedure looks good, i post the php code that i always use, it looks very similar but you can try to edit it.

<?php
      // Passphrase for the private key (ck.pem file)
      // $pass = ”;
      // Get the parameters from http get or from command line
      $message = 'Testo Notifica Push';
      $badge = 1;
      $sound = 'default';

      // Put your private key's passphrase here:
    $passphrase = '';

      // Construct the notification payload
      $body = array();
      $body['aps'] = array('alert' => $message);

      if ($badge)
            $body['aps']['badge'] = $badge;
      if ($sound)
            $body['aps']['sound'] = $sound;

      /* End of Configurable Items */

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

////////////////////////////////////////////////////////////////////////////////

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

// Open a connection to the APNS server
$fp = stream_socket_client(
    'ssl://gateway.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;

// Construct the notification payload
      $body = array();
      $body['aps'] = array(’alert’ => $message);

      if ($badge)
            $body['aps']['badge'] = $badge;
      if ($sound)
            $body['aps']['sound'] = $sound;

// 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);
?>
0
votes

One last step to do when setting up push is be sure you didn't mixed production and development device token! In my case, in my db the first device token the push was send to, was a development one. When this happens, Apple server kill the connection, avoid any other notification to be sent. Thanks Apple!