Saving data in app delegate - iphone

I have a couple of arrays i wish to save when the application terminates. I implemented this using NSUserDefaults within app delegate. Can anyone take a look at my code, and see whats wrong? It doesn't work whatsoever.
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
workouts = [NSMutableArray arrayWithObjects:nil];
menu = [NSMutableArray arrayWithObjects:#"Home",nil];
workoutNames = [NSMutableArray arrayWithObjects:nil];
routinesMade = [NSMutableArray arrayWithObjects:nil];
test = [NSMutableArray arrayWithObjects:nil];
defaults = [NSUserDefaults standardUserDefaults];
self.workouts = [defaults objectForKey:#"workouts"];
self.menu = [defaults objectForKey:#"menu"];
self.workoutNames = [defaults objectForKey:#"workoutNames"];
self.routinesMade = [defaults objectForKey:#"routinesMade"];
return YES;
}
- (void)applicationWillTerminate:(UIApplication *)application
{
defaults = [NSUserDefaults standardUserDefaults];
[defaults setObject:workouts forKey:#"workouts"];
[defaults setObject:menu forKey:#"menu"];
[defaults setObject:workoutNames forKey:#"workoutNames"];
[defaults setObject:routinesMade forKey:#"routinesMade"];
[defaults synchronize];
}
Btw, i declared defaults in the header file. Thanks guys!

I think I know what the problem is. Your code is inside the applicationWillTerminate: method. Unless you explicitly set your application not to run in background (by setting the 'Application does not run in background' key), it is almost certain that this method will never be called because by the time it gets terminated by the system, it will already have been suspended.
In this case consider saving the information you need in the applicationDidEnterBackground: method.
Hope this helps!

workouts and self.workouts are one property am i correct?
so you create array
workouts = [NSMutableArray arrayWithObjects:nil];
then override it with null because [defaults objectForKey:#"workouts"] contains null

Related

How to get the count of number of times the app launch iPhone

Im developing a reminder app.
So my client want to set a rate this application popup message, that'll come up on the 10th time user open the app.is this possible.
How can i implement this?
Can anyone help me please.Thanks in advance
You could use NSUserDefaults for this:
NSUserDefaults * userDefaults = [NSUserDefaults standardUserDefaults];
NSInteger appLaunchAmounts = [userDefaults integerForKey:#"LaunchAmounts"];
if (appLaunchAmounts == 10)
{
[self showMessage];
}
[userDefaults setInteger:appLaunchAmounts+1 forKey:#"LaunchAmounts"];
You can store that into the NSUserDefaults. Just update it in applicationDidFinishLaunching:.
You can save an integer in NSUserDefaults
- (void)setInteger:(NSInteger)value forKey:(NSString *)defaultName
Retrieve it and increment it every time the appDidFinishLaunching (or appWillEnterForeground) delegate methods is called. Probably best to use appWillEnterForeground as sometimes apps can lie in the background unterminated for days.
NSUserDefaults* defaults = [NSUserDefaults standardUserDefaults];
NSInteger count = [defaults integerForKey:#"LaunchCount"];
count++;
/* Do checks and review prompt */
[defaults setInteger:count forKey:#"LaunchCount"];
[defaults synchronize];
This will store a value in NSUserDefaults called 'AppLaunchCount'.
- (BOOL)application:(UIApplication *)app didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
if ([[NSUserDefaults standardUserDefaults] integerForKey:#"AppLaunchCount"])
{
[[NSUserDefaults standardUserDefaults] setInteger:([[NSUserDefaults standardUserDefaults] integerForKey:#"AppLaunchCount"] + 1) forKey:#"AppLaunchCount"];
}
else
{
[[NSUserDefaults standardUserDefaults] setInteger:1 forKey:#"AppLaunchCount"];
}
}

How to keep my data in a array-iphone sdk

I'm trying to create an application, and in that I'm receiving some contents from net and loading into and array, if I quit and run the app again i'm losing the data. How can I store the data in the app itself. Should I use some kind of database? If so which one and how can I implement that? I need to store only some string variables.
EDIT:
My app is tabbar based app, and have two tabs. Loading the arrays in one tab and loading that array in a table in the other VC. once I load the array and move to the second tab, the table is loaded with the array. If i go back and add few more values and then if i check, the added datas is not displayed in the table. And also, when I quit the app the table lose all the values, I need to keep the values in the table, even after i quit the app. How can I do that?
here is my code:
in viewdidload:
NSUserDefaults *simplePlistDb = [NSUserDefaults standardUserDefaults];
[simplePlistDb setBool:YES forKey:#"isItWorking"];
[simplePlistDb setObject:alertList forKey:#"myArray"];
[simplePlistDb synchronize];
in cellforrowatindexpath:-
NSUserDefaults *simplePlistDb = [NSUserDefaults standardUserDefaults];
BOOL flag = [simplePlistDb boolForKey:#"isItWorking"];
if (flag)
{
NSArray *myArray = [simplePlistDb objectForKey:#"myArray"];
for (NSString *str in myArray){
NSLog(#"Str:%#", str);
[loadArray addObject:str];
}
cell.textLabel.text = [loadArray objectAtIndex:indexPath.row];
}
Thank you.
You will want to look into Core Data if you want to save a decent amount of data to the iPhone. However, if not, you can just load the items in the array into a plist and load them from there at launch.
Plist Writing: How to create a new custom property list in iPhone Applications
CoreData: http://www.raywenderlich.com/934/core-data-tutorial-getting-started
Edit--->
As Nekto said, you can also use NSUserDefaults, but I advise mainly using NSUserDefaults for simple NSStrings and integers.
I think for your purposes NSUserDefaults will be enough : NSUserDefaults Class Reference.
Examples:
// save
NSUserDefaults *simplePlistDb = [NSUserDefaults standardUserDefaults];
[simplePlistDb setBool:YES forKey:#"isItWorking"];
[simplePlistDb setObject:[NSArray arrayWithObjects:#"very", #"cool", nil]];
[simplePlistDb synchronize];
// restore
NSUserDefaults *simplePlistDb = [NSUserDefaults standardUserDefaults];
BOOL flag = [simplePlistDb boolForKey:#"isItWorking"];
if (flag)
{
NSArray *myArray = [simplePlistDb objectForKey:#"myArray"];
for (NSString *str in myArray)
NSLog(#"%#", str);
}
You can use NSUserDefaults in order to store your data till the time your app is installed in your device.
How to write in NSuserDefaults:
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
[defaults setObject:#"yourObject1" forKey:#"correspopndingKey1"];
[defaults setObject:#"yourObject2" forKey:#"correspopndingKey2"];
[defaults synchronize];
How to read from NSuserDefaults:
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
NSString *temp1 = [defaults objectForKey:#"correspopndingKey1"];
NSString *temp2 = [defaults objectForKey:#"correspopndingKey2"];
You can store NSArray in a similar way.
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
[defaults setObject:objArray forKey:#"correspopndingKey"];
[defaults synchronize];

iPhone Strange Settings Problem

I am having unexpected results with my application. I am using a settings bundle, and I want to the default switch to turn on. The switches are off when I start my application. But the sound and the shake are working. I just want the switch to be one when my application loads, and the sound and the shake to be enabled.
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
// Set the application defaults
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
NSDictionary *appDefaults = [NSDictionary dictionaryWithObject:#"YES" forKey:#"enableSound"];
NSDictionary *appDefaults2 = [NSDictionary dictionaryWithObject:#"YES" forKey:#"enableShake"];
[defaults registerDefaults:appDefaults];
[defaults registerDefaults:appDefaults2];
[defaults synchronize];
return YES;
}
Here is part of the code for the sound button:
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
enabledSound = [defaults boolForKey:#"enableSound"];
Here is part of the code where I dectect the shake:
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
enabledSound = [defaults boolForKey:#"enableSound"];
enabledShake = [defaults boolForKey:#"enableShake"];
It turns out in the settings bundle, that the Value for OFF and the Value for ON should be removed, and the application worked.

NSUserDefaults doesn't save

i'm trying to save some informations in an iphone/ipad app.
The problem is that it works but if i close the app (with the home button on the simulator or closing with cmd+q) the informations become lost!
this is my code (and, if you see, i used "syncronize")
- (IBAction)choose1{
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
[defaults setObject:#"choose1" forKey:#"choose"];
[defaults synchronize];
}
- (IBAction)choose2{
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
[defaults setObject:#"choose2" forKey:#"choose"];
[defaults synchronize];
}
- (IBAction)openview{
NSString *var = [[NSUserDefaults standardUserDefaults] objectForKey:#"choose"];
if (var == #"choose1"){
[self pushViewController:view1 animated:YES];}
else if (var == #"choose2"){
[self pushViewController:view2 animated:YES];
}
}
I don't understand why :(
When comparing strings, you should use the isEqualToString method, ie:
if ([var isEqualToString:#"choose1"]){
Otherwise you are comparing actual objects rather than their contents.
I am not entirely sure, but maybe it is saving your defaults and the error is located somewhere else. I am thinking about your "openView" method:
- (IBAction)openview{
NSString *var = [[NSUserDefaults standardUserDefaults] objectForKey:#"choose"];
if (var == #"choose1"){
[self pushViewController:view1 animated:YES];}
/** you are comparing to "choose1" here as well. **/
else if (var == #"choose1"){
[self pushViewController:view2 animated:YES];
}
Another possibilty might be that you never call your choose1() or choose2() methods?
This would explain why the value is never changed.
Despite from these 2 possibilites I think there is no error in the code you use to change the UserDefaults.
Hope this helps.
Regards,
Gjallar
ah, i'm sorry: i'm italian so i used the word "choose" with the italian translation "scelta".
Here i translated in english and i wrote "choose1" but in my code i used "choose2" (or "scelta2" :P)
for the other possibility (that i've never called the function choose1() or choose2() )... no, i've called, of course!

Problem with NSUserDefaults and deallocated Instance

I'm having a problem with NSUserDefaults. I've followed the steps in the books as closely as I can for my app, but still get the same problem.
I am getting a
*** -[NSUserDefaults integerForKey:]: message sent to deallocated instance 0x3b375a0
error when I try and load in the settings. Here is the code that I have, it is in the App Delegate class.
- (void)applicationDidFinishLaunching:(UIApplication *)application {
recordingController = [[RecordingTableViewController alloc] initWithStyle:UITableViewStylePlain];
[recordingController retain];
// Add the tab bar controller's current view as a subview of the window
[window addSubview:tabBarController.view];
[self loadSettings];
}
-(void)loadSettings
{
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
NSNumber loop = [defaults objectForKey:#"loop_preference"];
NSNumber play = [defaults objectForKey:#"play_me_preference"];
NSNumber volume = [defaults objectForKey:#"volume_preference"];
}
As you can see I am not trying to do anything with the values yet, but I get the error on the line reading in the loop preference. I also get it if I try and read an NSString.
Any suggestions would be greatly appreciated.
Thanks
Peter
Since NSNumber is an object, it seems likely to me that you want:
NSNumber *loop = [defaults objectForKey:#"loop_preference"];
NSNumber *play = [defaults objectForKey:#"play_me_preference"];
NSNumber *volume = [defaults objectForKey:#"volume_preference"];
(Add asterisks * after NSNumber and before the variable names.) Though this does not seem directly related to your error message, it's the only apparent quirk in your code.