1

I used Ray Wenderlich's tutorial to help me in this. I ran through all of the setup, and tests using the SimplePush.php that he included, but with my device token. When I ran it from Terminal, it worked perfect! I got the notification instantly. So, I decided to run a more real-world test.

My app already uses a PHP file online to update the count by 1 in an XML file I have built that it uses. So, I copied the PHP code from SimplePush.php and pasted it in with the rest of the code that accomplishes this. I then uploaded my ck.pem into the same directory online. However, the Push never gets delivered. Here is the php in full:

<?php
$first_name = $_POST['first_name'];
 $last_name = $_POST['last_name'];
 $title = $_POST['title'];

$xml = simplexml_load_file("URL.xml") or die("Not loaded!\n");


$responses = $xml->xpath("//channel/item[title = '$title' and first_name = '$first_name' and last_name = '$last_name']/prayer_warriors");
$responses[0][0] = $responses[0] + 1;
echo($responses);
$xml->asXML("Test.xml");  
// Put your device token here (without spaces):
$deviceToken = 'MyDeviceToken';

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

// Put your alert message here:
$message = 'Someone just pledged to pray for you!';

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

$ctx = stream_context_create();
stream_context_set_option($ctx, 'ssl', 'local_cert', 'ck.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;

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

Does it have something to do with this line?

stream_context_set_option($ctx, 'ssl', 'local_cert', 'ck.pem');

It all works when it is local, but putting the php online along with my ck.pem and running the script doesn't work right.

More INFO:

In code, when I run the PHP, I simply have a POST command. Is that the issue, that since I'm posting, nothing is getting ran from the rest of it?

 NSData *myRequestData = [NSData dataWithBytes: [myRequestString UTF8String] length: [myRequestString length]];
    NSMutableURLRequest *request = [[NSMutableURLRequest alloc] initWithURL: [NSURL URLWithString: @"URL.php"]];
    // set Request Type
    [request setHTTPMethod: @"POST"];
    // Set content-type
    [request setValue:@"application/x-www-form-urlencoded" forHTTPHeaderField:@"content-type"];
    // Set Request Body
    [request setHTTPBody: myRequestData];
    // Now send a request and get Response
    NSData *returnData = [NSURLConnection sendSynchronousRequest: request returningResponse: nil error: nil];
    // Log Response
    NSString *response = [[NSString alloc] initWithBytes:[returnData bytes] length:[returnData length] encoding:NSUTF8StringEncoding];
    NSLog(@"Response%@",response);
user717452
  • 33
  • 14
  • 73
  • 149
  • What gets outputted by your PHP script? Does it say it failed to connect, or say that it sent the message? – Alex Blundell May 26 '14 at 16:47
  • @AlexBlundell How do I get output from the PHP script? – user717452 May 26 '14 at 17:03
  • Well, you're `NSLog`ing the response/output - what's the output of that? – Alex Blundell May 26 '14 at 17:09
  • @AlexBlundell literally all that came out was the word response. It did everything else in the PHP except the push notification. – user717452 May 26 '14 at 17:10
  • Error from PHP is [function.stream-socket-client]: unable to connect to ssl://gateway.push.apple.com:2195 (Connection timed out) in simplepush.php on line 21 – user717452 May 26 '14 at 17:30
  • Your issue therefore is your PHP script on the server can't talk to Apple's server. I had this issue - had to manually enable port 2195 on the firewall of the server (iptables, if you're using linux). If you're on a shared host, get them to enable the port – Alex Blundell May 26 '14 at 18:46

1 Answers1

0

This issue isn't related to an issue with the code, it's an issue with the configuration of the server the PHP script is running on. You need to enable an 'out' rule for port 2195 (and 2196 for feedback) to Apple's servers on your firewall.

Alex Blundell
  • 2,084
  • 5
  • 22
  • 31
  • I use Yahoo web hosting currently. What hosting sites allow for simple_xml_load to save an xml file, and have port 2195 open? – user717452 May 26 '14 at 18:54
  • Generally, shared hosting isn't recommended for Push servers. You need more control over the environment that only a VPS or Dedicated Server can provide. Free hosts almost certainly won't allow this, you'd have to ask paid ones but a lot still wouldn't enable it – Alex Blundell May 26 '14 at 18:56