3

I'm trying to use a php code to send to all tokens who downloaded my iPhone application. Could you tell me how to send to multiple devices and how to get into a loop of devices tokens?

this is my code:

<?php

$deviceToken = ''; // HERE I CAN SEND TO ONE DEVICE

// Passphrase for the private key (ck.pem file)
// $pass = '';
// Get the parameters from http get or from command line
$message = $_GET['message'] or $message = $argv[1] or $message = 'MY NOTIFICATION BODY';
$badge = (int)$_GET['badge'] or $badge = (int)$argv[2];
$sound = $_GET['sound'] or $sound = $argv[3];

// 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 */

$ctx = stream_context_create();
stream_context_set_option($ctx, 'ssl', 'local_cert', 'apns-dev.pem');
// assume the private key passphase was removed.
// stream_context_set_option($ctx, 'ssl', 'passphrase', $pass);
$fp = stream_socket_client('ssl://gateway.sandbox.push.apple.com:2195', $err, $errstr, 60,STREAM_CLIENT_CONNECT, $ctx);
if (!$fp) {
print "Failed to connect $err $errstrn";
return;
}
else {
print "Connection OK\n";
}

$payload = json_encode($body);
$msg = chr(0) . pack("n",32) . pack('H*', str_replace(' ', '', $deviceToken)) .      pack("n",strlen($payload)) . $payload;
print "sending message :" . $payload . "\n";
fwrite($fp, $msg);
fclose($fp);

?>
SalehAlmusallam
  • 118
  • 1
  • 2
  • 7

2 Answers2

10

I wrote a tutorial on push notifications. I suggest you read it so you will better understand what you're supposed to do: http://www.raywenderlich.com/3443/apple-push-notification-services-tutorial-part-12

Hollance
  • 2,958
  • 16
  • 15
  • I have done all what you mentioned on your great tutorial and it works fine, but I'm talking here about sending a single notification to multiple devices. Thanks – SalehAlmusallam Jun 17 '11 at 20:50
  • You should consider them multiple notifications. Each device needs to receive its own notification. So if you follow what my tutorial does and put a record in the database for each notification you wish to send out, you would put 100 records in the database if you wanted to send the same notification to 100 devices. If this is something you will do often -- sending the exact same notification to multiple devices -- then a different database structure might make more sense. – Hollance Jun 17 '11 at 20:56
  • 1
    So you're saying I should create my own database on my server and store all devices tokens by sending them from the app delegate application:didRegisterForRemoteNotificationsWithDeviceToken method to my server, then running a loop for push notification?or there is a way to get them from apple server? – SalehAlmusallam Jun 17 '11 at 21:06
  • Correct. When your app is installed on a user's device, it sends the token to your server. Your server needs to keep track of these tokens somehow, for example in a database. Then when you need to push a notification to these tokens, you get them from the database and send a notification to each one. There is no way to get a list of device tokens from Apple, you need to collect these yourself. (You can only send to devices that have your app on them, by the way. If you send too many notifications that cannot be delivered, Apple may blacklist your certificate.) – Hollance Jun 17 '11 at 22:48
  • Thank you so much Hollance that's great. I will send a single push notification to all clients every 2-3 days, is that too much? I couldn't find any article about how much I can send without being blacklisted. – SalehAlmusallam Jun 18 '11 at 12:59
  • You should be able to send many notifications. However, if you do, don't send up a new connection to APNS for every notification you send (but keep it open all the time). You can also open up to 15 concurrent connections per app. Finally, bundle as many notifications into a single packet that you send to APNS. This will reduce the impact your service has on APNS. – Hollance Jun 18 '11 at 23:41
  • That's Great, thanks for these good details you saved my time reading the long documentations. – SalehAlmusallam Jun 22 '11 at 14:55
  • @Hollance I have tried your method. I am trying to send the device token to my server. But the problem is my device token always turns out `(null)` can you please help? –  Mar 18 '13 at 10:30
  • @Hollance Here is my code: Here is my code: ` NSString *deviceTokenString = [[[deviceToken description] stringByReplacingOccurrencesOfString: @"<" withString: @""] stringByReplacingOccurrencesOfString: @">" withString: @""];NSString *strURL = [NSString stringWithFormat:@"http://www.mywebsite.net/addDeviceToken.php?devicetoken=%@", deviceTokenString]; NSData *dataURL = [NSData dataWithContentsOfURL:[NSURL URLWithString:strURL]]; NSString *strResult = [[NSString alloc] initWithData:dataURL encoding:NSUTF8StringEncoding]; } ` –  Mar 18 '13 at 10:31
2

Push messages have to be sent one by one. You'll have to use a foreach loop to loop through the device tokens:

Here's a simple example:

foreach ( $device_tokens as $device_token )
{
  // Send device token a message here.
}

Where $device_tokens is an array of device tokens.

Francois Deschenes
  • 24,816
  • 4
  • 64
  • 61
  • So the $device_tokens array comes from the apple server, is that true? How to test it before I upload the application to the app store? – SalehAlmusallam Jun 17 '11 at 20:53
  • 3
    @SalehAlmusallam - No. The iPhones app will send device tokens to you (assuming it's programmed to do that) and it's up to you to store the device tokens in a database. When you want to send push notification, you have to pull the records from your own database and send them. So to answer your question, the $device_tokens array is for you to populate with data (i.e. from a SQL query to your own database). – Francois Deschenes Jun 17 '11 at 21:02
  • Great Francois, that helped a lot, so you recommend I send the device token from this method `- (void)application:(UIApplication *)app didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken { NSString *str = [NSString stringWithFormat:@"Device Token=%@",deviceToken]; NSLog(@"%@",str); }` to my MySQL database using PHP and then retrieve them, put them on a loop. Thank you – SalehAlmusallam Jun 17 '11 at 21:10