iOS: Push Notification and Re-Registering the device at Login. - iphone

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.

Related

Saving a bool to NSdefaults on AppWillTerminate not working

I am trying to logout a user when the application is terminated (since in this particular case the user data doesn't change very often there is no need to logout when going into background).
So here is my code:
- (void)applicationWillTerminate:(UIApplication *)application
{
User *user = [[User alloc]init];
[user logout];
}
I first tried to log the user out like so but it didn't work:
- (void)applicationWillTerminate:(UIApplication *)application
{
[[NSUserDefaults standardUserDefaults] setBool:NO forKey:#"logged_in"];
}
Any ideas?
If you want the defaults to be updated immediately, you should sync after updating:
[[NSUserDefaults standardUserDefaults] synchronize];
As documented (khm, please look up the documentation), the NSUserDefaults class doesn't immediately persist the changes to disk, only once in a while.

Get device token to push notify the second time on iPhone

I need to obtain the device token on my iPhone to test the push notify.
On my iPhone I had already agreed to notify push permissions. I try to remove and reinstall the app but nothing. I try to put a breackpoint in the didRegisterForRemoteNotificationsWithDeviceToken method but nothing.
Any suggestion?
This is my code:
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
/**** PUSH NOTIFY ****/
[[UIApplication sharedApplication] registerForRemoteNotificationTypes:UIRemoteNotificationTypeAlert | UIRemoteNotificationTypeSound | UIRemoteNotificationTypeBadge];
self.window.rootViewController = self.tabBarController;
[self.window makeKeyAndVisible];
return YES;
}
- (void)application:(UIApplication *)app didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken {
NSMutableString *str = [[NSMutableString alloc] initWithFormat:#"http://www.mysite.com/storeToken.php?task=register&token=%#", [self stringWithDeviceToken:deviceToken]];
//NSLog(#"%#",str);
NSUserDefaults *pref = [NSUserDefaults standardUserDefaults];
[pref setObject:[self stringWithDeviceToken:deviceToken] forKey:#"token"];
[pref synchronize];
NSURL *url = [NSURL URLWithString:str];
ASIHTTPRequest *request = [ASIHTTPRequest requestWithURL:url];
[request startSynchronous];
[str release];
}
- (NSString*)stringWithDeviceToken:(NSData*)deviceToken {
const char* data = [deviceToken bytes];
NSMutableString* token = [NSMutableString string];
for (int i = 0; i < [deviceToken length]; i++) {
[token appendFormat:#"%02.2hhX", data[i]];
}
return [[token copy] autorelease];
}
This is the error that it print:
Error: Error Domain=NSCocoaErrorDomain Code=3000 "nessuna stringa di autorizzazione 'aps-environment' valida trovata per l'applicazione" UserInfo=0x296e80 {NSLocalizedDescription=nessuna stringa di autorizzazione 'aps-environment' valida trovata per l'applicazione}
It is good to have another delegate method for error handling:
- (void)application:(UIApplication *)application didFailToRegisterForRemoteNotificationsWithError:(NSError *)error {
NSLog(#"Fail to register for remote notifications: %#", [error localizedDescription]);
}
After question update it's more clear that problem is in wrong provisioning profile (generic or without 'aps-evironment'). So:
Remove all expired profiles and all profiles for that app from both XCode and device
Check push notifications are enabled for your app (in provisioning portal)
Download provisioning profile from portal, install it to XCode
Check that selected profile (in build settings / codesigning identity) matches the app, and is not the generic/wildcard one (sometimes autoselection goes wrong)
As usual (XCode caching "magic"), it's better to restart XCode and remove the application from device before build
Build & Pray

iPhone client not registering for push?

I "think" my app is not registering for push notifications.
It should be as simple as adding the code to didFinishLaunchingWithOptions and then the when tested the app alert for push notifications should (but does not in my case) pop up.
my code:
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
// Override point for customization after application launch.
self.window.rootViewController = self.viewController;
[self.window makeKeyAndVisible];
[[UIApplication sharedApplication] registerForRemoteNotificationTypes:(UIRemoteNotificationTypeAlert | UIRemoteNotificationTypeBadge |UIRemoteNotificationTypeSound)];
return YES;
}
This is an iPad app. It is running without push on my real device so I assume the provisioning is correct.
Any ideas? I do not get the push Don't allow/ok pop up.
Do u have this code in your delegate?
- (void)application:(UIApplication *)app didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken {
NSString *str = [NSString
stringWithFormat:#"Device Token=%#",deviceToken];
NSLog(str);
}
You should get the device token generated and put it in your server where you want to push your notification..
If let say you have everything right on the iphone part, the problem may lies on your server code where you push your notification..
Take a look at this tutorial about push notification :
http://mobiforge.com/developing/story/programming-apple-push-notification-services
You need to implement the delegate methods and set up the certificates on your server. Here is some code for the objc side:
- (void)application:(UIApplication *)app didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)devToken {
NSString *token = [[devToken description] stringByTrimmingCharactersInSet:[NSCharacterSet characterSetWithCharactersInString:#"<>"]];
[[NSUserDefaults standardUserDefaults] setObject:token forKey:#"token"];
[[NSUserDefaults standardUserDefaults] synchronize];
}
- (void)application:(UIApplication *)app didFailToRegisterForRemoteNotificationsWithError:(NSError *)err {
[[NSUserDefaults standardUserDefaults] setObject:[NSString stringWithString:#""] forKey:#"token"];
[[NSUserDefaults standardUserDefaults] synchronize];
}
- (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo {
UIAlertView *alert = [[[UIAlertView alloc] initWithTitle:[[[NSBundle mainBundle] infoDictionary] objectForKey:#"CFBundleDisplayName"]
message:[[userInfo objectForKey:#"aps"] objectForKey:#"alert"]
delegate:self
cancelButtonTitle:#"OK"
otherButtonTitles:nil] autorelease];
[alert show];
}
A good tutorial about setting up the server and Dev Center certs - How to renew your Apple Push Notification Push SSL Certificate
How to build an Apple Push Notification provider server (tutorial)
Yes I have the other part of the code also. I was under the impression that the pop up would happen weather the server stuff was done yet or not?
I got it working. I had to get a new provisioning file. Delete the old one. The go into the app folder. View contents of the project file. Open with text editor the file with the provisioning key in it and swap the key (two spots) out with the new key code.
Now it works. Thanks for the help.

Method to handle errors sending push-notification

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 ];
}

APNS - Getting device token

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.