Problem: My code appears to be executing fine, no errors, and proper log results, or so it appears, but no push notifications end up on the iPhone. I'm sending the notifications from Apache Tomcat running on a Mac: Mountain Lion.
Note: I can get this to run using the same certificates, except in .pem format in php. Javapns will not accept .pem so I use .p12 files. Since the .pem version of my certificates works in php I'm starting to suspect this entire problem is a shortcoming of javapns.
Background:
The code below executes without error and the notifications.isSuccessful() is actually returning true. But I am receiving no message on my device and no error. When I had previously utilized the wrong key I got appropriate errors, and when my token string was too long I had received errors. Now the application finally runs with no exception but nothing is reaching the device.
String keyFilePath = request.getServletContext().getRealPath("")+System.getProperty("file.separator")+"keys"+System.getProperty("file.separator")+"key.p12";
List<PushedNotification> notifications = Push.combined (pushNotificationMessage, 1, "Sound.wav", keyFilePath, "Password", false, userToken);
for (PushedNotification notification : notifications) {
if (notification.isSuccessful()) {
System.out.println("Push notification sent successfully to: " +
notification.getDevice().getToken());
} else {
String invalidToken = notification.getDevice().getToken();
Exception theProblem = notification.getException();
theProblem.printStackTrace();
/* If the problem was an error-response packet returned by Apple, get it */
ResponsePacket theErrorResponse = notification.getResponse();
if (theErrorResponse != null) {
System.out.println(theErrorResponse.getMessage());
}
}
}
LOGS
2014-05-16 20:29:21 DEBUG Payload:219 - Adding alert [blah blah blah]
2014-05-16 20:29:21 DEBUG Payload:193 - Adding badge [1]
2014-05-16 20:29:21 DEBUG Payload:205 - Adding sound [Sound.wav]
2014-05-16 20:29:21 DEBUG ConnectionToAppleServer:94 - Creating SSLSocketFactory
2014-05-16 20:29:21 DEBUG ConnectionToAppleServer:149 - Creating SSLSocket to gateway.sandbox.push.apple.com:2195
2014-05-16 20:29:22 DEBUG PushNotificationManager:111 - Initialized Connection to Host: [gateway.sandbox.push.apple.com] Port: [2195]: 5dec07cc[SSL_NULL_WITH_NULL_NULL: Socket[addr=gateway.sandbox.push.apple.com/17.172.232.45,port=2195,localport=51223]]
2014-05-16 20:29:22 DEBUG PushNotificationManager:538 - Building Raw message from deviceToken and payload
2014-05-16 20:29:22 DEBUG PushNotificationManager:617 - Built raw message ID 1 of total length 154
2014-05-16 20:29:22 DEBUG PushNotificationManager:396 - Attempting to send notification: {"aps":{"sound":"Sound.wav","alert":"blah blah blah","badge":1}}
2014-05-16 20:29:22 DEBUG PushNotificationManager:397 - to device: cb45519c4516907a03b3b5c2f0e48aa51f6f3d900cb7598f4e3c4482b33afea8
2014-05-16 20:29:22 DEBUG PushNotificationManager:415 - Flushing
2014-05-16 20:29:22 DEBUG PushNotificationManager:417 - At this point, the entire 154-bytes message has been streamed out successfully through the SSL connection
2014-05-16 20:29:22 DEBUG PushNotificationManager:420 - Notification sent on first attempt
2014-05-16 20:29:22 DEBUG PushNotificationManager:222 - Reading responses
2014-05-16 20:29:27 DEBUG PushNotificationManager:200 - Closing connection
Push notification sent successfully to: cb45519c4516907a03b3b5c2f0e48aa51f6f3d900cb7598f4e3c4482b33afea
Registration
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
UIRemoteNotificationType notificationTypes = [[UIApplication sharedApplication] enabledRemoteNotificationTypes];
if (notificationTypes != (UIRemoteNotificationTypeAlert | UIRemoteNotificationTypeBadge | UIRemoteNotificationTypeSound) ) {
[[UIApplication sharedApplication] registerForRemoteNotificationTypes:(UIRemoteNotificationTypeAlert | UIRemoteNotificationTypeBadge | UIRemoteNotificationTypeSound) ];
NSLog(#"Reregistering for notifications");
} else {
NSLog(#"Notifications Found");
}
return YES
}
Obtaining the Token
-(void)application:(UIApplication *)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken
{
NSString *stringToken = [[[[deviceToken description]
stringByReplacingOccurrencesOfString: #"<" withString: #""]
stringByReplacingOccurrencesOfString: #">" withString: #""]
stringByReplacingOccurrencesOfString: #" " withString: #""];
//[NSString stringWithFormat:#"%#",deviceToken];
[self sendPNToken:[NSString stringWithFormat:#"%#",stringToken]];
NSLog(#"StringToken: %#",stringToken);
}
System
Mountain Lion/Mac, Apache Tomcat, JDK 1.7
Related
I need to register the device for Push Notification each time the User Logs In.
Right now in my AppDelete.m I have the following code:
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
...
[[UIApplication sharedApplication] registerForRemoteNotificationTypes:UIRemoteNotificationTypeAlert];
}
- (void)application:(UIApplication *)app didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken
{
NSString *token = [[deviceToken description] stringByTrimmingCharactersInSet:[NSCharacterSet characterSetWithCharactersInString:#"<>"]];
token = [[token componentsSeparatedByString:#" "] componentsJoinedByString:#""];
[self.pushClient registerDeviceToken:token withUser:loggedInUserName onSuccess:^{
NSLog(#"successful registration");
} onFailure:^(NSError *error) {
NSLog(#"error: %#", [error userInfo]);
}];
}
Q. What do I need to do to call the above methods in my App Delegate each time the User Logs In? i.e. The app is running. A User logs out and logs back in with a different username, and now I need to register the device with that user name, what should I do?
You can always call the method registerForRemoteNotificationTypes after user is logged in.
You need to persist APNS token, thats the way going forward for your situation.
As and when your app comes to foreground, you will get call in registerForRemoteNotificationTypes. Now
remove old APNS token from NSUserDefaults if any (or whatever you like for persistence)
save APNS token into NSUserDefaults
and use saved token.
I want to send the device token to server in my application. I am using following method to retrieve the device token.
- (void)application:(UIApplication *)app didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken {
NSLog(#"deviceToken: %#", deviceToken);
}
but not worked in ios6. How can do this?
Have you written this line
[[UIApplication sharedApplication] registerForRemoteNotificationTypes:
(UIRemoteNotificationTypeBadge | UIRemoteNotificationTypeSound | UIRemoteNotificationTypeAlert)];
inside this function,
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
It should work in iOS 6 if you have done this.
If you are using Urbanariship you need to clean up the deviceToken before sending it back via a NSURLConnection PUT to the urbanairship servers.
NSString *deviceToken = [[_deviceToken description] stringByReplacingOccurrencesOfString: #"<" withString: #""];
deviceToken = [deviceToken stringByReplacingOccurrencesOfString: #">" withString: #""] ;
deviceToken = [deviceToken stringByReplacingOccurrencesOfString: #" " withString: #""];
Other wise you can send using NSURequest/ NSURLConnection
Hope this will help you out. or just let us know if you want code for Request and Connection as well.
I m making an iOS notification service. But my device dont receive anything, i just take one tutorial from internet and make it.
I send more than 1 notification at time, maybe its this the problem? I have my app properly implemented (i can see it in settings).
The correct question for me is... Are there some methods you can use to see if there is any code to handle errors in sending the notifications?
Thank you.
In the Apple Documentation, look at :
Table 5-1 Codes in error-response
packet
You will find what you search.
Hi There are few methods in pushnotification whice are as below
First register your device by
[[UIApplication sharedApplication] registerForRemoteNotificationTypes:(UIRemoteNotificationTypeAlert | UIRemoteNotificationTypeBadge | UIRemoteNotificationTypeSound)];
Then use its delegate methods
- (void)application:(UIApplication *)app didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)devToken
{
NSLog(#"Before --- Token === %#",devToken);
NSString *strServerResponse = [[[devToken description] stringByTrimmingCharactersInSet:[NSCharacterSet characterSetWithCharactersInString:#"<>"]]copy];
NSLog(#"%#",strServerResponse);
NSString * encodedURL = (NSString *)CFURLCreateStringByAddingPercentEscapes(NULL,(CFStringRef)strServerResponse,NULL,(CFStringRef)#" ",kCFStringEncodingUTF8 );
NSString *DeviceToken=[Constant getUserDefaultValueForKey:#"DeviceToken"];
if([Constant checkStringNull:DeviceToken])
{
[Constant setUserDefaultValue:encodedURL forKey:#"DeviceToken"];
}
NSLog(#"After Encoding --- Token === %#",encodedURL);
}
- (void)application:(UIApplication *)app didFailToRegisterForRemoteNotificationsWithError:(NSError *)err
{
NSLog(#"Error in registration. Error: %#", err);
}
- (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo
{
NSLog(#"userInfo %#",userInfo);
[UIApplication sharedApplication].networkActivityIndicatorVisible=TRUE;
NSLog(#"\n\nData Received From Push Notification ===== %#",[userInfo description]);
[[UIApplication sharedApplication]setApplicationIconBadgeNumber:0 ];
}
i edit and modify the provisioning profile alot of times. and i checked it in text editor too. everything is ok with provisioning profile. but still push notifications are not working. and i m getting this error. everyone is saying that its bcz of bad provisioning profile but my provisioning profile values are the same as Apple said in their documentation. i m getting this error:
Error in registration. Error: Error Domain=NSCocoaErrorDomain
Code=3000 "no valid 'aps-environment' entitlement string found for
application" UserInfo=0x127d80 {NSLocalizedDescription=no valid
'aps-environment' entitlement string found for application}
code lookes like this in my AppDelegate.m:
- (BOOL)application:(UIApplication )application didFinishLaunchingWithOptions:(NSDictionary )launchOptions {
[[UIApplication sharedApplication] registerForRemoteNotificationTypes:(UIRemoteNotificationTypeBadge | UIRemoteNotificationTypeSound | UIRemoteNotificationTypeAlert)];
[self.window addSubview:navigationController.view];
[self.window makeKeyAndVisible];
return YES;
}
-(void)application:(UIApplication )application didRegisterForRemoteNotificationsWithDeviceToken:(NSData )deviceToken {
NSString *deviceTokenStr = [[[[deviceToken description] stringByReplacingOccurrencesOfString: #"<" withString: #""] stringByReplacingOccurrencesOfString: #">" withString: #""] stringByReplacingOccurrencesOfString: #" " withString: #""];
NSLog(#"DeviceTokenStr: %#",deviceTokenStr);
}
Thanx for help in advance
I believe the "no valid 'aps-environment' entitlement string found for application" error appears when you don't sign your app with the correct provisioning profile. You'll have to generate a profile for your app as described in Mahesh's link). Also note that you can't use a team provisioning profile to sign an app that requires push notifications.
I am going to implement push notifications in my app with the AppNotify service. To finish setting that service up I need to get my device token. I have tried using the code from Apple's docs. On the simulator I get an error (expected of course). On my device I do not get an error, but I do not get the token either. Neither delegate method is called. Here is the code (first bit goes in applicationDidFinishLaunching):
[[UIApplication sharedApplication] registerForRemoteNotificationTypes:(UIRemoteNotificationTypeBadge | UIRemoteNotificationTypeSound | UIRemoteNotificationTypeAlert)];
- (void)application:(UIApplication *)app didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)devToken {
//const void *devTokenBytes = [devToken bytes];
//self.registered = YES;
//[self sendProviderDeviceToken:devTokenBytes]; // custom method
NSLog(#"Success");
NSLog(#"Token = %#", devToken);
}
- (void)application:(UIApplication *)app didFailToRegisterForRemoteNotificationsWithError:(NSError *)err {
NSLog(#"Error in registration. Error: %#", err);
}
Any ideas why this is happening?
Thanks
Once, you must know that remote notifications doesn't work on simulator.
Regards
add the following method as well:
- (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo
{
for (id key in userInfo)
{
NSLog(#"key: %#, value: %#", key, [userInfo objectForKey:key]);
}
}
If you have written the right code (as you show) one of the above 3 methods (the 2 you have written and the one i have above) gets called. If you don't get any error on the device then wait for some time (ideally 10 seconds but it maybe take longer as well) for the didRegisterForRemoteNotificationsWithDeviceToken method to get called. Regards.