NSInvalidArgumentException in didreceivelocalnotifiaction - iphone

I am bit bit confused as why am I geting this NSInvalidArgumentException error as I am not doing anything special.Here is my code do let me if I have done anything wrong.Basically i am implementing the the Mixpanel analytics in didreceivelocalnotifiaction and sending the fire time to the mixpanel.I have stored the value for username.Please let me know why am I getting this error.Moreover its not regular,it comes once in a while so that is making more difficult to find the error.
- (void)application:(UIApplication *)app didReceiveLocalNotification:(UILocalNotification *)notif {
// Handle the notificaton when the app is running
Mixpanel *mixp = [Mixpanel sharedInstance];
[mixp track:#"Notification Fired" properties:[NSDictionary dictionaryWithObject:notif.fireDate forKey:#"App Opens"]];
mixp.nameTag = [[NSUserDefaults standardUserDefaults] objectForKey:#"Username"];
[mixp identify:[[NSUserDefaults standardUserDefaults] objectForKey:#"Username"]];
}

Related

NSUserDefaults values becoming nil

I am observing strange behaviour of NSUserDefaults. During testing on iphone 4(32-bit) it is working fine. When i send the same app to my client using iPhone 5S(64-bit), NSUserDefault values are becoming nil. Is the behaviour of NSUserDefaults is changing on 32-bit and 64-bit ios versions? I have also used [[NSUserDefaults standardUserDefaults]synchronize] after saving values in NSUserDefaults.I am observing this kind of behaviour from ios 7.1 versions.
AppDelegate.m
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
//to stop updating locations in subsequent launches
if (![#"1" isEqualToString:[[NSUserDefaults standardUserDefaults]
objectForKey:#"aValue"]]) {
//Action here
NSLog(#"LOCATION IS ON");
locationManager = [[CLLocationManager alloc] init];
locationVC = [[LocationVC alloc]init];
[locationVC InitializeWith:_managedObjectContext LocationManager:locationManager];
//[locationVC InitializeWith:_managedObjectContext LocationManager:nil];
}
else {
NSLog(#"LOCATION IS OFF");
locationManager = [[CLLocationManager alloc] init];
locationVC = [[LocationVC alloc]init];
//[locationVC InitializeWith:_managedObjectContext LocationManager:locationManager];
[locationVC InitializeWith:_managedObjectContext LocationManager:nil];
}
}
LocationVC.m
LocationVC *locationVC;
-(void) InitializeWith:(NSManagedObjectContext *)context LocationManager:(CLLocationManager *)locationManager{
//to update location during first launch
if (![#"1" isEqualToString:[[NSUserDefaults standardUserDefaults]
objectForKey:#"aValue"]]) {
[[NSUserDefaults standardUserDefaults] setValue:#"1" forKey:#"aValue"];
[[NSUserDefaults standardUserDefaults] synchronize];
NSLog(#"LOCATION IS ON");
self->locationManager=locationManager;
self->locationManager.delegate = self;
self->locationManager.desiredAccuracy = kCLLocationAccuracyBest;
self->locationManager.distanceFilter = kCLDistanceFilterNone;
[self->locationManager startUpdatingLocation];
_managedObjectContext=context;
}
//in subsequent launches
else{
NSLog(#"LOCATION IS OFF");
_managedObjectContext=context;
[self->locationManager stopUpdatingLocation];
}
}
In my client's iPhone 5S(64-bit), location icon is reappearing after 10 minutes eventhough i have called [self->locationManager stopUpdatingLocation]; in subsequent application lauches.
Is the behaviour of NSUserDefaults is changing on 32-bit and 64-bit ios versions?
No, NSUserDefaults (based on property lists) are designed to be platform independent. You can even copy a binary plist file from a Power PC Mac to an Intel machine, an iPhone 32 bit, or iPhone 64 bit and the file will always produce identical results.
The NSUserDefaults class is known to be very robust.
It's very likely that the error is in your code. If you need more help, please provide more information about how you detect and reproduce the error.
Edit: It seems that you used the wrong method to set #"aValue":
[[NSUserDefaults standardUserDefaults] setValue:#"1" forKey:#"aValue"];
The correct method to set preferences is -setObject:forKey:.
setValue:fortKey: is part of KVC and is not documented to do something specific in NSUserDefaults. While it seems that in current implementations (iOS 7.1) NSUserDefaults overrides setValue:forKey: that's an undocumented feature not guaranteed to work as expected.

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.

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.