I tried several times to send push notifications to my applications, but to no avail. I followed many textbooks and followed all the steps. I receive successful messages from the APNS server, but not a single message arrives on the device. I tested sending using the resulting development certificate, and I generated the appropriate production certificates and use them in the php script. I will post my code below. Please let me know if you see something that I am doing wrong. I just donβt know what it is ...
Any help would be greatly appreciated.
<?php $link=mysqli_connect('****','****','****','***'); if(mysqli_connect_errno()) { header('HTTP/1.1 400'); header('Content-type: text/html'); echo 'Connection Error: %s\n',mysqli_connect_error(); exit; } echo "Connected to Database<br />"; echo "Querying Database<br />"; switch ($_REQUEST['App']) { case "O2": $query="SELECT Token FROM O2CalculatorPushTokens"; break; case "LZA": $query="SELECT Token FROM LZAPushTokens"; break; case "MorseCode": $query="SELECT Token FROM MorseCodePushTokens"; break; default: echo "Unknown App."; exit; } $result=mysqli_query($link,$query); echo mysqli_num_rows($result)."<br />"; if ($result==false) { echo "No tokens to send to."; } else { //Set SSL context $ctx = stream_context_create(); echo "Loading SSL Certificate...<br>"; switch($_REQUEST['App']) { case "O2": stream_context_set_option($ctx, 'ssl', 'local_cert', 'SSL/O2CalculatorProductionSSL.pem'); break; case "LZA": stream_context_set_option($ctx, 'ssl', 'local_cert', 'SSL/LandingZoneAssistantProductionSSL.pem'); break; case "MorseCode": stream_context_set_option($ctx, 'ssl', 'local_cert', 'SSL/MorseCodeProductionSSL.pem'); break; default: exit; } echo "Unlocking SSL Certificate...<br><br>"; stream_context_set_option($ctx, 'ssl', 'passphrase', '****'); //Open a connection to the APNS server echo "Connecting to APNS server...<br>"; $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<br><br>"); else echo "Connected to APNS!<br />"; //Create the payload body echo "Creating message...<br>"; $body['aps'] = array('alert' => $_REQUEST['PushMessageTextArea']); echo $body."<br>"; //Encode the payload as JSON echo "Encoding message...<br>"; $payload = json_encode($body); echo $payload."<br>"; while($row=mysqli_fetch_assoc($result)) { //Build the binary notification echo "Sending message to ".$row['Token']."<br>"; $msg = chr(0).pack('n',32).pack('H*',$row['Token']).pack('n',strlen($payload)).$payload; //Send it to the server $PushResult = fwrite($fp, $msg, strlen($msg)); if (!$PushResult) echo "Message not delivered! <br />"; else echo "Message successfully delivered! <br />"; }; //Close connection to the server echo "Closing APNS connection...<br><br>"; fclose($fp); mysqli_free_result($result); } mysqli_close($link);
And my iPhone script ...
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { // Override point for customization after application launch. //Register for push notifications [[UIApplication sharedApplication] registerForRemoteNotificationTypes:(UIRemoteNotificationTypeAlert)]; return YES; } - (void)application:(UIApplication*)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData*)deviceToken { if (![[NSUserDefaults standardUserDefaults] boolForKey:@"registeredForPush"]) { //Remove spaces and brackets from deviceToken NSString* token = [deviceToken description]; token = [token stringByTrimmingCharactersInSet:[NSCharacterSet characterSetWithCharactersInString:@"<>"]]; token = [token stringByReplacingOccurrencesOfString:@" " withString:@""]; NSMutableString *params = [[NSMutableString alloc] initWithFormat:@"Token="]; [params appendString:token]; NSMutableURLRequest *request = [[NSMutableURLRequest alloc] initWithURL:[NSURL URLWithString:@"http://www.bluelineapps.net/****.php"] cachePolicy:NSURLRequestReloadIgnoringCacheData timeoutInterval:100.0]; [request setHTTPMethod:@"POST"]; [request setHTTPBody:[params dataUsingEncoding:NSUTF8StringEncoding]]; NSURLConnection *connection = [[NSURLConnection alloc] initWithRequest:request delegate:self]; if (connection) { //Show alert UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Thank you!" message:@"Thank you for registering for updates. Please rate this app in the AppStore after you've had some time to use it. Feedback is welcome and can be sent using the 'Feedback' tab below. Enjoy!" delegate:self cancelButtonTitle:@"Ok" otherButtonTitles:nil, nil]; [alert dismissWithClickedButtonIndex:0 animated:TRUE]; [alert show]; } else { //Show Error UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Registration error!" message:@"Failed to register for updates. Please try again later in your 'Settings' app. Sorry for the inconvenience." delegate:self cancelButtonTitle:@"Ok" otherButtonTitles:nil, nil]; [alert dismissWithClickedButtonIndex:0 animated:TRUE]; [alert show]; } [[NSUserDefaults standardUserDefaults] setBool:TRUE forKey:@"registeredForPush"]; [[NSUserDefaults standardUserDefaults] synchronize]; } } - (void)application:(UIApplication*)application didFailToRegisterForRemoteNotificationsWithError:(NSError*)error { NSLog(@"Failed to get token, error: %@", error); } - (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo { UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Landing Zone Assistant" message:[userInfo valueForKeyPath:@"alert"] delegate:self cancelButtonTitle:@"Ok" otherButtonTitles:nil, nil]; [alert show]; } @end
UPDATE:
So, after deleting all the mobile Provisioning profiles, all certificates, all .pem files, everything and re-creating all the certificates, keys, permissions and profiles for development and production, my problem still remains ...
A message was sent to debug the version on the device using the sandbox gateway successfully. Sent message to release version in Ad Hoc version on test device using Apple's main gateway, failed ....
Any ideas?
I do not receive error messages from APNS, everything is successful. No build errors. New updated certificates ...
UPDATE:
I found this article from Apple Technical Support here and followed all the steps and checked everything. As far as I can tell, everything checks. My build assembly contains aps_environment of Production, as it should be.
I also found this method for creating .pem files, which was slightly different than my previous attempts, so I tried this and it still does not work. My code is still the same as above, since the problem seems to be in a different place, but if someone sees something while scanning through PLEASE, let me know. I just want it to work.
I would gladly put generosity on this question, but I do not have a sufficient reputation for this, and I am trying to get something by helping my other questions.
UPDATE:
During the search, I found another document from Apple here , which has a line that says: "Please note that the device token in the production environment and the device token in the development environment (sandbox) are not the same value." Therefore, I assume that there will be another question.
Is deviceToken different for development and production modes?
UPDATE:
I know this is a long time, but I'm trying to show what steps I have taken to try to solve this problem myself.
I continue to see this Entrust CA certificate appear in the documentation. I used this to test the connection to the APNS gateway, but I do not use it in my connection when sending push messages, because none of the examples that I saw show its use. Is this required, and if so, how to use it?
UPDATE:
I decided to try using PhoneGap to reprogram my applications and attract additional audiences, so I will close it for now. Thank you all for your help.