Apple Push Notification Service connects, but no n

2019-09-11 03:05发布

问题:

I’ve been banging my head on the wall trying to get this work for the past week. I just started again from scratch and logged everything that I did and it still does not work. Here are the steps i’ve taken:

1) Create a new App ID Identifier using a new bundle id (the old one did not have push notifications)

a) made sure push notifications were added to the app id and proceeded to the last step, this resulted in an app id with push notifications in the ‘configurable’ state.

b) I then went to edit the app id and saw that i could create a new production or development certificate so i did both using the steps listed

2) Created two new provisioning profiles, one for dev and one for production, both are using the new bundle id

3) import the new provisioning profiles into Xcode and make sure that those are the ones selected in the build settings

4) create the .p12 files by using the keychain and exporting the .cer files for dev and production

5) create the .pem file from the .p12 files using these commands:

openssl pkcs12 -in VX-Mobile-Dev.p12 -out apns-dev.pem -nodes -clcerts

openssl pkcs12 -in VX-Mobile-Prod.p12 -out apns-prod.pem -nodes -clcerts 

6) Next created a php script (that i blatantly ripped off from another blog) that i run from the command line of one of my virtual machines. In the same folder as that file i put the pans-prod.pem file. Here is the contents of that file

Note, for the device token i simply run the app from Xcode where it already successfully connects to the apns server and gets a device token which gets logged out into the console, for testing purposes i am just copying the new token into the file each time.

File contents:

// set time limit to zero in order to avoid timeout
set_time_limit(0);

// charset header for output
header('content-type: text/html; charset: utf-8');

// this is the pass phrase you defined when creating the key
$passphrase = '{passphrase is hidden to you!}';

// you can post a variable to this string or edit the message here
if (!isset($_POST['msg'])) {
$_POST['msg'] = "Notification message here!";
}

// function for fixing Turkish characters
function tr_to_utf($text) {
    $text = trim($text);
    $search = array('Ü', 'Þ', 'Ð', 'Ç', 'Ý', 'Ö', 'ü', 'þ', 'ð', 'ç', 'ý', 'ö');
    $replace = array('Ãœ', 'Åž', 'Ğž', 'Ç', 'Ä°', 'Ö', 'ü', 'ÅŸ', 'ÄŸ', 'ç', 'ı', 'ö');
    $new_text = str_replace($search, $replace, $text);
    return $new_text;
}

// tr_to_utf function needed to fix the Turkish characters
$message = tr_to_utf($_POST['msg']);

// load your device ids to an array
$deviceIds = array(
'97c8c0a77e1380d052d17352e33b1f2224f082a3436ee90310cf88c7278329e7'
);

// this is where you can customize your notification
$payload = '{"aps":{"alert":"' . $message . '","sound":"default"}}';

$result = 'Start' . "\r\n";

////////////////////////////////////////////////////////////////////////////////
// start to create connection
$ctx = stream_context_create();
stream_context_set_option($ctx, 'ssl', 'local_cert', 'apns-prod.pem');
stream_context_set_option($ctx, 'ssl', 'passphrase', $passphrase);

echo count($deviceIds) . " devices will receive notifications.\r\n";

foreach ($deviceIds as $item) {
    // wait for some time
    sleep(1);

    // 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" . "\r\n");
    } else {
        echo 'Apple service is online. ' . "\r\n";
    }

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

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

    if (!$result) {
        echo 'Undelivered message count: ' . $item . "\r\n";
    } else {
        echo("\r\nRESULT\r\n\r\n");
        var_dump($result);
        echo("\r\n\r\n");
        echo 'Delivered message count: ' . $item . "\r\n";
    }

    if ($fp) {
        fclose($fp);
        echo 'The connection has been closed by the client' . "\r\n";
    }
}

echo count($deviceIds) . " devices have received notifications.\r\n";

// set time limit back to a normal value
set_time_limit(30);

Please help.

回答1:

Turns out i was almost there. The only problem was that i should have been using the sandbox endpoint.

ssl://gateway.sandbox.push.apple.com:2195

Also, in response to RJV Kumar, once i got it working i tried it with both my prod and my dev certificate and it worked in both cases. This seems suspicious to me but whatever i'm just glad that its working.

[UPDATE]

While the steps in this post are technically correct, i learned that you should NOT create a new App ID if you actually want to be able to release a new version of your app. Instead of doing this you should simply add push notifications to your current App ID.