i'm developing an app that need push notification.
I'm following this tutorial to implement push notification with php.
So i'm using production certificate.
This is the code in the applicationDelegate:
- (void)application:(UIApplication *)app didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken {
const unsigned* tokenBytes = [deviceToken bytes];
NSString* tok = [NSString stringWithFormat:#"%08x%08x%08x%08x%08x%08x%08x%08x",
ntohl(tokenBytes[0]), ntohl(tokenBytes[1]), ntohl(tokenBytes[2]),
ntohl(tokenBytes[3]), ntohl(tokenBytes[4]), ntohl(tokenBytes[5]),
ntohl(tokenBytes[6]), ntohl(tokenBytes[7])];
NSLog([NSString stringWithFormat:#"token 1 = %#",tok]);
[[NSUserDefaults standardUserDefaults] setObject:tok forKey:#"token"];
}
- (void)application:(UIApplication *)app didFailToRegisterForRemoteNotificationsWithError:(NSError *)err {
}
- (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo {
NSLog(#"Received notification: %#", userInfo);
}
and this is the server side php page:
<?php
//$token = $_GET['t'];
$token = "xxxxxxxxxxx....xxxxxx";
$who =$_GET['c'];
$notification = $_GET['n'];
$message = 'Hello';
$badge = 3;
$sound = 'default';
$payload = array();
$payload['aps'] = array('alert' => $message, 'badge' => intval($badge), 'sound' => $sound);
$payload = json_encode($payload);
$apns_url = NULL;
$apns_cert = NULL;
$apns_port = 2195;
$apns_url = 'gateway.push.apple.com';
$apns_cert = 'cert-prod.pem';
$stream_context = stream_context_create();
stream_context_set_option($stream_context, 'ssl', 'local_cert', $apns_cert);
$apns = stream_socket_client('ssl://' . $apns_url . ':' . $apns_port, $error, $error_string, 2, STREAM_CLIENT_CONNECT, $stream_context);
$device_tokens = array();
$device_tokens[0] = $token;
foreach($device_tokens as $key=>$device_token)
{
$apns_message = chr(0) . chr(0) . chr(32) . pack('H*', str_replace(' ', '', $device_token)) . chr(0) . chr(strlen($payload)) . $payload;
fwrite($apns, $apns_message);
}
#socket_close($apns);
#fclose($apns);
?>
Nothing happen when i launch php page.. why? who can help me?
i think your token isnt correct. try:
NSString *token = [NSString stringWithCString:[deviceToken bytes]];
this should help:
NSString *deviceTokenStr = [[[[deviceToken description]
stringByReplacingOccurrencesOfString: #"<" withString: #""]
stringByReplacingOccurrencesOfString: #">" withString: #""]
stringByReplacingOccurrencesOfString: #" " withString: #""];
NSLog(#"Device Token: %#", deviceTokenStr);
Related
I have generated PASS with my code and also get device id, pushtoken in response from device.
here is code by which I am store all device and Pass information in database.
$params = array(
"get"=>$_GET,
"request"=>$_REQUEST,
"post"=>$_POST,
"server"=>$_SERVER
);
$url = $_SERVER['SCRIPT_URI'];
$myfile = file_put_contents('callback.txt', json_encode($params).PHP_EOL , FILE_APPEND | LOCK_EX);
$content = trim(file_get_contents("php://input"));
$myfile = file_put_contents('log.txt', $content.PHP_EOL , FILE_APPEND | LOCK_EX);
$header = json_encode(getallheaders());
$myfile = file_put_contents('header.txt', $header.PHP_EOL , FILE_APPEND | LOCK_EX);
/*
* store registered device data
* */
$str = $_SERVER['SCRIPT_URI'];
$str = stripslashes($str);
$url_slot = parse_url($str);
$urlArray = explode('/',$url_slot['path']);
$passid = $urlArray['11']; // serial no
$deviceId = $urlArray['8'];
$passtype = $urlArray['10'];
try {
$dbh = new PDO('mysql:host=localhost;dbname=''', 'yyyy', 'zzzz');
$stmt = $dbh->prepare("INSERT INTO devices_passes (device_id, pass_id, pass_type, created, modified) VALUES
(:device_id,:pass_id,:pass_type,:created,:modified)");
$stmt->bindParam(':device_id', $device_id);
$stmt->bindParam(':pass_id', $pass_id);
$stmt->bindParam(':pass_type', $pass_type);
$stmt->bindParam(':created', date('d-m-y'));
$stmt->bindParam(':modified', date('d-m-y'));
$device_id = $deviceId;
$pass_id = $passid;
$pass_type = $passtype;
$stmt->execute();
$dbh = null;
} catch (PDOException $e) {
print "Error!: " . $e->getMessage() . "<br/>";
die();
}
try {
$dbh = new PDO('mysql:host=localhost;dbname=yyyy', 'uuuuu', 'yyyyyy');
$stmt = $dbh->prepare("INSERT INTO devices (push_token) VALUES
(:push_token)");
$stmt->bindParam(':push_token', $push_token);
$push_token = $content['pushToken'];
$stmt->execute();
$dbh = null;
} catch (PDOException $e) {
print "Error!: " . $e->getMessage() . "<br/>";
die();
}
But when I send push notification to device , it will not reflect anything in device.
here is code of sending push notification to device.
<?php
$apnsHost = 'gateway.push.apple.com';
$apnsPort = 2195;
$apnsCert = 'apple_push_notification_production.pem';
$push_token = 'my token';
$passIdentify = 'pass.yyyyy.xxxx';
$payload = '{}';
$msg = chr(0) . pack('n', 32) . pack('H*', $push_token) . pack('n', strlen($payload)) . $payload . pack('n', strlen($passIdentify)) . $passIdentify;
$streamContext = stream_context_create();
stream_context_set_option($streamContext, 'ssl', 'local_cert', $apnsCert);
$apns = stream_socket_client('ssl://' . $apnsHost . ':' . $apnsPort, $error, $errorString, 2, STREAM_CLIENT_CONNECT, $streamContext);
fwrite($apns, $msg);
#socket_close($apns);
fclose($apns);
?>
Can you please help me when I am going wrong ??
Push notification badge count not increasing.It shows always 1.I have used php to send the push from server and here is the code following:
$apnsHost = 'gateway.sandbox.push.apple.com';
$apnsCert = 'project_dev.pem';
$apnsPort = 2195;
$badgecount=1;
$streamContext = stream_context_create();
stream_context_set_option($streamContext, 'ssl', 'local_cert', $apnsCert);
$apns = stream_socket_client('ssl://' . $apnsHost . ':' . $apnsPort, $error, $errorString, 2, STREAM_CLIENT_CONNECT, $streamContext);
if (!$apns){
exit("Failed to connect: $error $errorString" . PHP_EOL);
}else{
$messageHeader = (strlen($message) > 26) ? substr($message,0,26).'...' : $message;
$msgd=explode(':',$message);
$payload['aps'] = array('alert' => $messageHeader,'badge' => $badgecount, 'sound' => 'default','mess'=>$fromUserId.'||'.$userNamee.'||'.$userimage.'||'.$message,'type'=>'reply', 'unread_count'=>$unread_count);
$output = json_encode($payload);
$token = pack('H*', str_replace(' ', '', $token));
$apnsMessage = chr(0) . chr(0) . chr(32) . $token . chr(0) . chr(strlen($output)) . $output;
fwrite($apns, $apnsMessage);
fclose($apns);
}
badgecount always send by server side.it seems you are sending $badgecount=1; always.Update it with other value then check.It definitely reflect on IOS.
In your code you have send your badge always one that's why you getting only $badgecount 1 badge into application side.
you need to use following type to send notification badge.
$query = "SELECT badgecount FROM pushnotifications WHERE device_token = '{$device_token}'";
$query = $this->db->query($query);
$row = $query->row_array();
$updatequery = "update pushnotifications set badgecount=badgecount+1 WHERE device_token ='{$device_token}'";
$updatequery = $this->db->query($updatequery);
$device = $device_token;
$payload['aps'] = array('alert' => $pushmessage, 'badge' =>$row["badgecount"]+1, 'sound' => 'default');
$payload = json_encode($payload);
I think you now more clearify with above code.
This is the code that I am using for notification from PHP to iOS
#--------------- initializations ------------------------------
$message = substr($message, 0, 255);
$sound = 'default';
$development = true;
$badge = '1';
$payload['aps'] = array(
'alert' => $message,
'badge' => intval($badge),
'sound' => $sound
);
$payload = json_encode($payload);
$apns_url = NULL;
$apns_cert = NULL;
$apns_port = 2195;
#-------------------------(/initializations)---------------
// developement or live server certificate
if($development)
{
$apns_url = 'gateway.sandbox.push.apple.com';
$apns_cert = __DIR__.'/app_dev.pem';
}
else
{
$apns_url = 'gateway.push.apple.com';
$apns_cert = __DIR__.'/app_prod.pem';
}
$stream_context = stream_context_create();
stream_context_set_option($stream_context, 'ssl', 'local_cert', $apns_cert);
$apns = stream_socket_client('ssl://' . $apns_url . ':' . $apns_port, $error, $error_string, 60, STREAM_CLIENT_CONNECT|STREAM_CLIENT_CONNECT, $stream_context);
$device_tokens = $receivers;
foreach($device_tokens as $device_token)
{
$apns_message = chr(0) . chr(0) . chr(32) . pack('H*', str_replace(' ', '', $device_token)) . chr(0) . chr(strlen($payload)) . $payload;
$result = fwrite($apns, $apns_message,strlen($apns_message));
}
#socket_close($apns);
fclose($apns);
The error I am getting is
Warning: stream_socket_client(): unable to connect to
ssl://gateway.sandbox.push.apple.com:2195 (Connection timed out)
Can anybody see what is wrong with code ?I have read many posts related to this but nothing is helping me .
i have a little problem with my PHP Code.
I did not get it to work, that the message i sent, will receive on all Devices witch are saved in my Database.
The Push App on the Device registers automatically the deviceToken in my MySQL Database. That is all working fine.
The big problem is, that i get the Push Message only to the FIRST Device from the Database. The other Device don't receive any message.
Here my code:
<?php
require_once('konfiguration.php');
$sql = "SELECT deviceToken FROM DeviceTokens";
$dbquery = mysql_query($sql);
// check checkboxes
$message = $_POST['alert'];
$badge = $_POST['badge'];
$sound = $_POST['sound'];
// Construct the notification payload
$body = array();
// anti-error variable
$nothing = true;
// get user input
if ($message) { $alert=$_POST['message']; $nothing = false;
$body['aps']['alert'] = $alert; }
if ($badge) { $nothing = false;
if($_POST['number']) $number=(int)$_POST['number'];
else $number=1;
$body['aps']['badge'] = $number; }
if ($sound) { $nothing = false;
$body['aps']['sound'] = 'beep.wav'; }
// if input not correct, scream
if ($nothing || ($message && $alert=="")) { echo "Falscher Input!"; exit(); }
//make new stream context
$ctx = stream_context_create();
// set parameters
$streamContext = stream_context_create();
stream_context_set_option($streamContext, 'ssl', 'local_cert', 'w3workProd.pem');
//stream_context_set_option($streamContext, 'ssl', 'passphrase', 'nils');
$socketClient = stream_socket_client('ssl://gateway.push.apple.com:2195', $error,
$errorString, 60, STREAM_CLIENT_CONNECT, $streamContext);
$payload = json_encode($body);
print "sending message :" . $payload . "\n";
while($row = mysql_fetch_array($dbquery)) {
$message = chr(0) . chr(0) . chr(32) . pack('H*', str_replace(' ', '', $deviceToken))
.chr(0) . chr(strlen($payload)) . $payload;
$deviceToken = str_replace(' ', '', $row['deviceToken']);
$message = pack('CnH*', 0, 32, $deviceToken);
$message = $message . pack('n', strlen($payload));
$message = $message . $payload;
fwrite($socketClient, $message);
echo ($row['deviceToken']);
}
fclose($socketClient);
exit();
?>
Would be nice if you can help.
Why is it working with one Device...and not with the others...
have you tried
STREAM_CLIENT_CONNECT|STREAM_CLIENT_PERSISTENT
?
I am implementing a push notification in my application.
Server: php
Client: iphone
Sever side Coding:
function pushToIphone($deviceToken, $badge){
ini_set('display_errors','on');
error_reporting(E_ALL);
//$apnsHost = 'gateway.sandbox.push.apple.com';
$apnsHost = 'gateway.push.apple.com';
$apnsPort = 2195;
$pem_path = dirname(__FILE__);
$pem_path = $pem_path .'\cert';
$apnsCert = $pem_path.'\apns_cer.pem';
echo $apnsCert."<br/>";
$streamContext = stream_context_create();
stream_context_set_option($streamContext, 'ssl', 'local_cert', $apnsCert);
$apns = stream_socket_client('ssl://' . $apnsHost . ':' . $apnsPort, $error, $errorString, 2, STREAM_CLIENT_CONNECT, $streamContext);
if($apns) {
echo "Connection Established<br/>";
$payload = array();
//$payload['aps'] = array('alert' => 'BiiMe finds product for you', 'badge' => $badge, 'sound' => 'default');
//$payload = get_payload_message('BiiMe finds product for you',$badge);
//$payload['server'] = array('serverId' => $serverId, 'name' => $serverName);
//$payload = json_encode($payload);
$payload = get_payload_message('BiiMe finds product for you',$badge);
$apnsMessage = chr(0) . chr(0) . chr(32) . pack('H*', str_replace(' ', '', $deviceToken)) . chr(0) . chr(strlen($payload)) . $payload;
echo $apnsMessage."<BR/>";
$fwrite = fwrite($apns, $apnsMessage);
echo $fwrite." bytes written<BR/>";
} else {
echo "Connection fail<br/>";
}
//socket_close($apns);
fclose($apns);
}
function get_payload_message($message_text,$badge,$sound='default')
{
$PAYLOAD_MAXIMUM_SIZE = 256;
$payload['aps'] = array("alert" => "$message_text", 'badge' => $badge, 'sound' => $sound);
$payload = json_encode($payload);
$nJSONPayloadLen = strlen($payload);
if($nJSONPayloadLen > $PAYLOAD_MAXIMUM_SIZE)
{
$nTextLen = strlen($message_text);
if($nJSONPayloadLen - $nTextLen <= $PAYLOAD_MAXIMUM_SIZE)
{
$badge_count = substr($message_text, 0, $nTextLen - ($nJSONPayloadLen - $PAYLOAD_MAXIMUM_SIZE));
$payload = get_payload_message($message_text);
}
}
return $payload;
}
Iphone side i added:
- (void)application:(UIApplication *)app didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken {
NSLog(#"It comes<<<<<<<<<<<<<---------------------------------------");
NSString *str = [NSString
stringWithFormat:#"Device Token=%#",deviceToken];
NSLog(str);
NSString *token = [NSString stringWithFormat:deviceToken];
NSUserDefaults *prefs = [NSUserDefaults standardUserDefaults];
[prefs setObject:token forKey:#"deviceId"];
}
- (void)application:(UIApplication *)app didFailToRegisterForRemoteNotificationsWithError:(NSError *)err {
NSLog(#"It comes with error---------------------------->>>>>>>>>>>>>>");
NSString *str = [NSString stringWithFormat: #"Error: %#", err];
NSLog(str);
NSUserDefaults *prefs = [NSUserDefaults standardUserDefaults];
[prefs setObject:str forKey:#"deviceId"];
}
- (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo {
for (id key in userInfo) {
NSLog(#"key: %#, value: %#", key, [userInfo objectForKey:key]);
}
}
also i use:
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
UIImageView *loading = [[UIImageView alloc] initWithFrame:CGRectMake(0, 20, 320, 460)];
[loading setImage:[UIImage imageNamed:#"Default.png"]];
[window addSubview:loading];
[loading release];
[[UIApplication sharedApplication] registerForRemoteNotificationTypes:(UIRemoteNotificationTypeAlert|UIRemoteNotificationTypeBadge|UIRemoteNotificationTypeSound)];
}
This is my whole code that used:
iPhone Log shows while Device is Connected:
2012-02-03 19:51:32.872 BiiMe[7544:707] It comes<<<<<<<<<<<<<---------------------------------------
2012-02-03 19:51:32.873 BiiMe[7544:707] Device Token=<26d906c5 c273446d 5f40d2c1 73ddd3f6 869b2666 b1c7afd5 173d69b6 629def70>
all times server side:
Connection Established
What is missing by me..? or what should i implemented in my code:
your answer will help me.
use this code in didFinishLaunchingWithOption in AppDelegete
[[UIApplication sharedApplication]
registerForRemoteNotificationTypes:(UIRemoteNotificationTypeBadge |
UIRemoteNotificationTypeSound |
UIRemoteNotificationTypeAlert)];
gateway.push.apple.com is used for released application or AdHoc application. If you are checking with development profile you might need to change it to gateway.sandbox.push.apple.com
Hope this helps.