I am trying to implement push notification in iOS in PHP using APNS library. Here is my code :
<?php
// Put your device token here (without spaces):
$deviceToken = 'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXX';
// Put your private key's passphrase here:
$passphrase = 'XXXXXX';
// Put your alert message here:
$message = 'My first push notification!';
////////////////////////////////////////////////////////////////////////////////
$ctx = stream_context_create();
stream_context_set_option($ctx, 'ssl', 'local_cert', 'Certificates.pem');
stream_context_set_option($ctx, 'ssl', 'passphrase', $passphrase);
// Open a connection to the APNS server
$fp = stream_socket_client(
'ssl://gateway.sandbox.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));print_r($result);
if (!$result)
echo 'Message not delivered' . PHP_EOL;
else
echo 'Message successfully delivered' . PHP_EOL;
// Close the connection to the server
fclose($fp);
?>
It show message sending successfully but in iOS it does not show notification.
2015-07-28 08:32:39 Connected to APNS result = 97
2015-07-28 08:32:39 Message successfully delivered
2015-07-28 08:32:39 Connection closed to APNS
Why this is happening? Am I missing anything ?
his mistake is with the ios 9 if so stop using the code in objective C and use in swift as it has a bug in generating objectiv token - C for ios9.
I recommend urgent change your code.
Also through this thought was the server when the scheduled ios changed for swift everything was resolved and my php was almost equal.
Care:
$ msg = chr (0). pack ('N', 32). pack (H * ','. '$deviceToken [0].'). pack ('N', strlen ($ payload)). $ payload;
There are two potential reason that is causing this:
Your app is in foreground
Your device token is invalid
In my app. I am directly getting deviceToken that's in NSData
- (void)application:(UIApplication *)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken
{
NSString *deviceTokenString = [NSString stringWithFormat:#"%#", deviceToken];
// this is producing something like:
// <xxxxxxx 9b0f527f xxxxxxxx 2727ed28 xxxxxxxx 4e693a61 xxxxxxx ac2f7dbb>
//
// and i am directly saving that to my servers database
Here's what i have in my server.
$from_database = "<xxxxxxx 9b0f527f xxxxxxxx 2727ed28 xxxxxxxx 4e693a61 xxxxxxx ac2f7dbb>";
// this removes the '<' and '>' to make the device token valid
//
$token_string = substr($from_database, 1, -1);
$token_array[] = $token_string;
// you can also add multiple 'token_string' to the 'token_array' for push notification broadcasting, i am currently doing that and it is working properly.
...
public function __push_notification($message_input, $token_array)
{
$message = stripslashes($message_input);
$passphrase = 'xxxxxx';
$cert = realpath('xxx.pem');
$payload = '{
"aps" :
{
"alert" : "'.$message.'",
"badge" : 1,
"sound" : "bingbong.aiff"
}
}';
$ctx = stream_context_create();
stream_context_set_option($ctx, 'ssl', 'local_cert', $cert);
stream_context_set_option($ctx, 'ssl', 'passphrase', $passphrase);
$fp = stream_socket_client('ssl://gateway.sandbox.push.apple.com:2195', $err, $errstr, 60, STREAM_CLIENT_CONNECT|STREAM_CLIENT_PERSISTENT, $ctx);
if (!$fp)
{
// echo "Failed to connect $err $errstr <br>";
return;
}
else
// echo "Post notification sent<br>";
$dev_array = array();
$dev_array = $token_array;
foreach ($dev_array as $device_token)
{
$msg = chr(0) .
pack("n", 32) .
pack('H*', str_replace(' ', '', $device_token)) .
pack("n", strlen($payload)) .
$payload;
// echo "sending message :" . $payload . "n";
fwrite($fp, $msg);
}
fclose($fp);
}
Also check this, might be helpful: Facing problems in ios push notification php code
Related
I am trying to migrate an existing API that used APNs to send and receive messages to be compatible with the new APNs Provider API.
The following script worked for sending test notifications to my testing device before Apple stopped supporting the legacy binary protocol.
//simplepush.php
<?php
// Put your device token here (without spaces):
$deviceToken = 'EXAMPLETOKEN';
// Put your private key's passphrase here:
$passphrase = 'pushchat';
// Put your alert message here:
$message = 'Hello!';
////////////////////////////////////////////////////////////////////////////////
$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://api.sandbox.push.apple.com:443', $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);
Sending Notification Requests to APNs states that the :method and :path header fields are required for a connection to APNs.
I've copied the code from the link to the original test script.
<?php
HEADERS
- END_STREAM
+ END_HEADERS
:method = POST
:scheme = https
:path = /3/device/EXAMPLETOKEN
host = api.sandbox.push.apple.com
apns-id = eabeae54-14a8-11e5-b60b-1697f925ec7b
apns-push-type = alert
apns-expiration = 0
apns-priority = 10
DATA
+ END_STREAM
{ "aps" : { "alert" : "Hello" } }
// Put your device token here (without spaces):
$deviceToken = 'EXAMPLETOKEN'; // Put your private key's passphrase here:
$passphrase = 'pushchat';
// Put your alert message here:
$message = 'Hello!';
///////////////////////////////////////////////////////////////////. /////////////
$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://api.sandbox.push.apple.com:443', $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);
When I try to run the script, the terminal output is:
PHP Parse error: syntax error, unexpected token ":" in /Users/Desktop/simple push folder/simplepush.php on line 6
What is the correct way to add the newly required header fields to this script?
Note: I've used the following Apple documentation to send a test notification to my testing advice.
PHP said that your file have a syntax error. I believe it has nothing to do with request header.
I try to send multiple notifications with one hit. Many users have more than one device and i put their device tokens into an array. It is working fine but if there is a wrong token Apple is disconnecting me and the device with working token gets no push notification. I've read about a error-response-solution at this post: Apple Push Notification Limits
But this solution is not working for me. It says: Status:7-Invalid payload size.
But there is only the message "test" and I'm sure the reason is the wrong token. How could I continue the foreach script without disconnecting?
// Put your device token here (without spaces):
$deviceToken = array('WRONG_TOKEN', 'WORKING_TOKEN');
// Put your private key's passphrase here:
$passphrase = 'PASS';
// Put your alert message here:
$message = "test";
////////////////////////////////////////////////////////////////////////////////
$ctx = stream_context_create();
stream_context_set_option($ctx, 'ssl', 'local_cert', 'cer.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' => "www/sound.mp3",
'content-available' => 1,
'badge' => 1
);
// Encode the payload as JSON
$payload = json_encode($body);
//foreach für array
foreach($deviceToken as $token){
$msg = chr(0) . pack('n', 32) . pack('H*', $token) . pack('n', strlen($payload)) . $payload;
// Send it to the server
$result = fwrite($fp, $msg, strlen($msg));
}//foreach end
if (!$result)
echo 'Message not delivered' . PHP_EOL;
else
echo 'Message successfully delivered' . PHP_EOL;
//checkAppleErrorResponse($fp);
// Close the connection to the server
fclose($fp);
I am using following code to send push notification to ios devices. I am getting successfully delivered message in php side but not receiving push in iOS device.
I have checked with replacing .pem files nd also tested with sendbox and production both. Its not working both. Please provide me the way of debugging this issue.
function iosTest($tToken)
{
// Provide the Host Information.
//$tHost = 'gateway.sandbox.push.apple.com';
$tHost = 'gateway.push.apple.com';
$tPort = 2195;
//echo "hi";
// Provide the Certificate and Key Data.
$tCert = $_SERVER['DOCUMENT_ROOT'].'/N****d.pem';
// Provide the Private Key Passphrase (alternatively you can keep this secrete
// and enter the key manually on the terminal -> remove relevant line from code).
// Replace XXXXX with your Passphrase
$tPassphrase = 'harsh';
// Provide the Device Identifier (Ensure that the Identifier does not have spaces in it).
// The message that is to appear on the dialog.
$tAlert = 'Testing..';
// The Badge Number for the Application Icon (integer >=0).
$tBadge = 1;
// Audible Notification Option.
$tSound = 'default';
// The content that is returned by the LiveCode "pushNotificationReceived" message.
$tPayload = 'APNS Message Handled by LiveCode';
// Create the message content that is to be sent to the device.
$tBody['aps'] = array (
'alert' => $tAlert,
'badge' => $tBadge,
'sound' => $tSound,
);
//$tBody ['payload'] = $tPayload;
// Encode the body to JSON.
$tBody = json_encode ($tBody);
echo $tBody;
// Create the Socket Stream.
$tContext = stream_context_create ();
stream_context_set_option ($tContext, 'ssl', 'local_cert', $tCert);
// Remove this line if you would like to enter the Private Key Passphrase manually.
stream_context_set_option ($tContext, 'ssl', 'passphrase', $tPassphrase);
// Open the Connection to the APNS Server.
$tSocket = stream_socket_client ('ssl://'.$tHost.':'.$tPort, $error, $errstr, 30, STREAM_CLIENT_CONNECT|STREAM_CLIENT_PERSISTENT, $tContext);
// Check if we were able to open a socket.
if (!$tSocket)
exit ("APNS Connection Failed: $error $errstr" . PHP_EOL);
// Build the Binary Notification.
$tMsg = chr (0) . chr (0) . chr (32) . pack ('H*', $tToken) . pack ('n', strlen ($tBody)) . $tBody;
// Send the Notification to the Server.
$tResult = fwrite ($tSocket, $tMsg, strlen ($tMsg));
if ($tResult)
echo 'Delivered Message to APNS' . PHP_EOL;
else
echo 'Could not Deliver Message to APNS' . PHP_EOL;
// Close the Connection to the Server.
fclose ($tSocket);
//send_feedback_request();
}
Thanks in advance.
Kindly use the following code as it working on my end
<?php
// Put your device token here (without spaces):
$deviceToken = '17b2f31afd5c9736ad48ffca8d1936046431c6fc1f3f3ac661bcbfbf97ca60cc';
// Put your private key's passphrase here:
$passphrase = '';
////////////////////////////////////////////////////////////////////////////////
$ctx = stream_context_create();
stream_context_set_option($ctx, 'ssl', 'local_cert', 'HireRightNew.pem');
stream_context_set_option($ctx, 'ssl', 'passphrase', $passphrase);
// Open a connection to the APNS server
$fp = stream_socket_client(
'ssl://gateway.sandbox.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' => 'Breaking News',
'sound' => 'default',
'link_url' => $url,
'category' => 'NEWS_CATEGORY',
);
// 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);
?>
I have the following php code for ios push notification.Here i code for 2 devices using loop in fwrite() section . the current code is working properly . My doubt is , can i pass the array of device tokens directly without using the for loop?.
<?php
// Put your device token here (without spaces):
$deviceToken[0] = 'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx';
$deviceToken[1] = 'yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy';
// Put your private key's passphrase here:
$passphrase = '123456';
// Put your alert message here:
$message = 'multiple device push notification...!';
////////////////////////////////////////////////////////////////////////////////
$ctx = stream_context_create();
stream_context_set_option($ctx, 'ssl', 'local_cert', 'abc.pem');
stream_context_set_option($ctx, 'ssl', 'passphrase', $passphrase);
// Open a connection to the APNS server
$fp = stream_socket_client(
'ssl://gateway.sandbox.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',
'badge' => '+1'
);
// Encode the payload as JSON
$payload = json_encode($body);
for($i=0;$i<2;$i++)
{
// Build the binary notification
$msg = chr(0) . pack('n', 32) . pack('H*', $deviceToken[$i]) . pack('n', strlen($payload)) . $payload;
// Send it to the server
$result = fwrite($fp, $msg, strlen($msg));
echo "msg may be delivered";
}
if (!$result)
echo 'Message not delivered' . PHP_EOL;
else
echo 'Message successfully delivered' . PHP_EOL;
// Close the connection to the server
fclose($fp);
Its design by default, yet there is no option for passing array of device tokens. You have to iterate through the loop.
Alternate to this approach will be using third party like amazon SNS service. Here you can publish to topic(one request) and all devices that are subscribed to this topic will receive the notification.
I am using a PHP script to send push notifications to my device. Here is what I use
$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.sandbox.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',
'id' => '10'
);
// 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;
echo "to $deviceToken.";
// Close the connection to the server
fclose($fp);
I get it successfully. I tap the view button, and I am trying to read the 'id' variable like this:
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
// Check for push notification info
NSDictionary *pushInfo = [launchOptions valueForKey:UIApplicationLaunchOptionsRemoteNotificationKey];
if (pushInfo)
{
// TODO: Pull the poke's info from our server and update the UI to display it
NSLog(#"Here's the id: %#", [pushInfo valueForKey:#"id"]);
}
return YES;
}
However, I don't get a NSLog when in mutitasking. I have yet to try it when I close the app because I cannot run console after you close out.
I even tried this:
- (void)application:(UIApplication *)app didReceiveLocalNotification:(UILocalNotification *)notif {
// Handle the notificaton when the app is running
NSLog(#"Recieved Notification %#",notif);
}
If I send the notification when running, I don't even get a NSLog. What's going on?
Thanks in advance!
NSDictionary *pushInfo = [launchOptions valueForKey:#"UIApplicationLaunchOptionsRemoteNotificationKey"] objectForKey:#"aps"]];