save and load highscore - objective-c

i tried to use NSUserDefults to save and load a highscore(nsinteger) for my game.
i created an void function that check if the gameoverscore is bigger than my highscore and if it does to switch between them. i want that every time the game is over there will be a label which show my currect highscore.
to do this, i create a property for my NSUsweDefults, in my viewdidload i tried to load the currect highscore, and another function (checkIfHighscore).
here is my NSUserDefults property:
#property(readwrite) NSUserDefaults *prefs;
here is my viewdidload code:
NSInteger currectHighscore = [prefs integerForKey:#"highscore"];
highScoreLabel.text = [NSString stringWithFormat:#"%d",currectHighscore];
here is my checkIfHighscore:
-(void)checkIfHighScore
{
if(gameOverScore > highScore)
{
highScore = gameOverScore;
[self newHighscoreAnimation];
[prefs setInteger:highScore forKey:#"highscore"];
[prefs synchronize];
}
highScoreLabel.text = [NSString stringWithFormat:#"Highscore: %d", highScore];
}
when i enter to this viewcontroller my highscorelabel shows 0, like it doesnt save my highscore.
what do i do wrong?
thanks!

// Snippet used to save your highscore in the prefs.
int highScore = yourGameScore;
[[NSUserDefaults standardUserDefaults] setObject:[NSNumber numberWithInt:highScore] forKey:#"HighScore"];
[[NSUserDefaults standardUserDefaults] synchronize];
// Snippet used to get your highscore from the prefs.
highScore = [[[NSUserDefaults standardUserDefaults] objectForKey:#"HighScore"] intValue ];

Related

How to save fields correctly with NSUserDefaults?

I'm creating a program that saves a String from one text field and an integer from a second text field. I am trying to use NSUserDefaults, but I can't seem to get either of them to save correctly when I run the program. It crashes when I press the save button with the breakpoint while handling the NSUserDefaults. Am I doing something wrong? I skimmed through the documentation, but it didn't help. Can I even use 2 different instances of NSUserDefaults?
- (IBAction)save:(id)sender {
//Save stuff fropm textfields
NSString* name = _nameText.text;
int count = [_countText.text intValue];
NSUserDefaults* defaults = [NSUserDefaults standardUserDefaults];
[[NSUserDefaults standardUserDefaults] setObject:name forKey:#"name"];
[[NSUserDefaults standardUserDefaults] setInteger:count forKey:#"count"];
[[NSUserDefaults standardUserDefaults] synchronize];
}
- (IBAction)load:(id)sender {
//Load stuff from NSUserDefaults
NSUserDefaults* defaults = [NSUserDefaults standardUserDefaults];
NSString* loadstring = [defaults objectForKey:#"name"];
_nameText.text = loadstring;
NSUserDefaults* defaults2 = [NSUserDefaults standardUserDefaults];
NSInteger loadint = [defaults2 integerForKey:#"count"];
_countText.text = [NSString stringWithFormat:#"%li", (long)loadint];
}
Declare defaults = [NSUserDefaults standardDefaults]; in your viewDidLoad (and NSUserDefaults* defaults; in .h) and use this code:
- (IBAction)save:(id)sender {
//Save stuff fropm textfields
NSString* name = _nameText.text;
int count = [_countText.text intValue];
[defaults setObject:name forKey:#"name"];
[defaults setInteger:count forKey:#"count"];
[defaults synchronize];
}
- (IBAction)load:(id)sender {
//Load stuff from NSUserDefaults
_nameText.text = [defaults stringForKey:#"name"];
_countText.text = [NSString stringWithFormat:#"%li", (long)[defaults integerForKey:#"count"]];
}

Creating a primary key with NSUserDefaults

Im using the code below to create a unique i.d. for primary keys or where every I need them in a program. The code works and there is never any errors but sometimes during debugging I noticed that it does not always increment still with no errors.
Can the code be improved for reliability?
- (NSString*)createUniqueID
{
//create a unique ID
int currentID = [[[NSUserDefaults standardUserDefaults] valueForKey:#"kUniqueID"] intValue];
currentID++;
NSString *returnID = [NSString stringWithFormat:#"%i", currentID];
[[NSUserDefaults standardUserDefaults] setValue:returnID forKey:#"kUniqueID"];
[[NSUserDefaults standardUserDefaults] synchronize]; //added sync
return returnID;
}
seems you need to call synchronize function
[[NSUserDefaults standardUserDefaults] synchronize];

Setting value in nsuserdefaults

I'm new to Objective-C and XCode and I've encountered such a problem.
How do you properly save the value to NSUserDefaults.
I have value in
[_textFields objectAtIndex:2]).text
And trying to do this
[[[NSUserDefaults standardUserDefaults] setValue:((UITextField *)[_textFields objectAtIndex:2]).text)) forKey:#"Phone"];
[[NSUserDefaults standardUserDefaults] synchronize];
How do you do it properly?
Use setObject:forKey: instead of setValue:forKey:
[[[NSUserDefaults standardUserDefaults] setObject:((UITextField *)[_textFields objectAtIndex:2]).text)) forKey:#"Phone"];
Update:
You code will work if you really have that text field in the array. Here is the step by step broken down code to make it more clear:
UITextField* textField = [_textFields objectAtIndex:2]; // get your text field
NSString* text = textField.text; // get the actual value we are going to store
[[[NSUserDefaults standardUserDefaults] setObject:text forKey:#"Phone"]; // store it
You are working with strings values. You should use setObjectForKey (save) and objectForKey (read). Here's an example
NSUserDefaults *userDefaults = [NSUserDefaults standardUserDefaults];
NSString *yourText = [[_textFields objectAtIndex:2] text]; // Your text
// Save
[userDefaults setObject:yourText forKey:kKey];
[userDefaults synchronize];
// Read
NSString *result = (NSString *) [userDefaults objectForKey:kKey];
Use method setObject:forKey: instead of setValue:forKey:
In NSUserDefaults class:
[[NSUserDefaults standardUserDefaults] setObject:"Your Object" forKey:#"Phone"];
You need to use the setObject:forKey: if you want to store property list objects (dictionaries, arrays, strings and numbers) in NSUserDefaults. See the docs.

How to Read String from NSUserDefaults

I have an object at the root of plist that stores objects and keys (one of which is input from a user textfield). I have no problem writing and creating structure; it's trying to read values that causing problem. Below code I used to write the data, can someone tell me how to read the string [val] and [myKey]?
thank you!
#define defaultValue #"Your Name"
#define myKey #"PersonName"
- (void)textFieldAction:(id)sender {
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
NSString *val;
// Get the new value from the textfield
val = [myTextField stringValue];
if ([val isEqualToString:defaultValue]) {
[defaults removeObjectForKey:myKey];
} else {
// [defaults setObject:val forKey:myKey];
NSDictionary *my_dict = [NSDictionary dictionaryWithObjectsAndKeys:
#"Name", #"PersonName",
#"Email", #"PersonEmail",
#"Dept", #"PersonDept",
#"Job", #"PersonJob",
val, myKey,
#"Status", #"PersonStatus",
nil];
[defaults setObject: my_dict forKey: #"Person"];
[[NSUserDefaults standardUserDefaults] registerDefaults:my_dict];
I would like to automatically populate the textfield with the [val], for [myKey], if the user has the info already in the plist. Here's the code I'm trying to use for that:
- (void)applicationDidFinishLaunching:(NSNotification *)notification {
NSUserDefaults *defaults = [[NSUserDefaults standardUserDefaults] objectForKey:myKey];
NSString *val = [defaults stringForKey:myKey];
if (val == nil) val = defaultValue;
[myTextField setStringValue:val];
You can write the value into NSUserDefault like the following:
[[NSUserDefaults standardUserDefaults] setValue:[myTextField stringValue] forKey:#"Person"];
And read it later like the following:
[myTextField setStringValue:[[NSUserDefaults standardUserDefaults] stringForKey:#"Person"];
So you can simplify your code into:
- (void)textFieldAction:(id)sender {
[[NSUserDefaults standardUserDefaults] setValue:[myTextField stringValue] forKey:#"Person"];
[[NSUserDefaults standardUserDefaults] synchronize];
}
You can set a default value with the registerDefaults:. And when you can retrieve that value simply by calling:
- (void)applicationDidFinishLaunching:(NSNotification *)notification
{
// ...
[[NSUserDefaults standardUserDefaults] registerDefaults:#{#"Person", defaultValue}]
NSString *value = [[NSUserDefaults standardUserDefaults] stringForKey:#"Person"];
[myTextField setStringValue:value];
// ...
}
If I understand correctly, you should be able to do what you need by simply doing:
NSString * val = [[NSUserDefaults standardUserDefaults] objectForKey: myKey];
[textfield setText: val];
NSUserDefaults Reference Page
myTextField.text = [[NSUSerDefaults standardUserDefaults] objectForKey:myKey];

save bool in nsuserdefaults

when my app starts music is playing:
-(void)playBgMusic {
NSString *path = [[NSBundle mainBundle] pathForResource:#"bgmusic" ofType:#"aif"];
theAudio = [[AVAudioPlayer alloc] initWithContentsOfURL:[NSURL fileURLWithPath:path] error:NULL];
theAudio.delegate = self;
[theAudio play]; }
but he should be able to turn the music off by pressing a button if he presses the button again the music should turn on again. i have:
-(IBAction)check {
if (isquiet == NO) {
[theAudio stop];
isquiet = YES;
defaults = [NSUserDefaults standardUserDefaults];
[defaults setBool:YES forKey:#"stringKey"];
}
else {
[self playBgMusic];
isquiet = NO;
defaults = [NSUserDefaults standardUserDefaults];
[defaults setBool:NO forKey:#"stringKey"]; } }
I think I didn't get it. Now it works in my first ViewController that I can turn the music on and off but when I go to another viewController while the music is playing, then back again and press the button, the music doesn't stop and when i press it many times the music is played a second time and overlaps.
What's still wrong?
No need to wrap it in an NSNumber, there are some convenience methods for this:
To set a BOOL, use:
[userDefaults setBool:YESorNO forKey:#"yourKey"];
To access it, use:
[userDefaults boolForKey:#"yourKey"];
[EDIT TO ANSWER YOUR ADDITIONAL QUESTION]
Not sure why you are using NSUserDefaults - it seems unnecessary for what you are trying to achieve? Here's what I would do for a button that can start/stop music:
-(IBAction)check
{
if (isQuiet)
{
// Play music
// Change the button to indicate it is playing...
} else
{
// Stop music
// Change the button to indicate it has stopped...
}
// Set your isQuiet to be the opposite of what it was when the button was clicked
isQuiet = !isQuiet;
}
Box your BOOL value to NSNumber object and add it to NSUserDefault:
NSUserDefaults *boolUserDefaults = [NSUserDefaults standardUserDefaults];
[boolUserDefaults setObject:[NSNumber numberWithBool:isquiet]
forKey:#"stringKey"];
Later you'll be able to retrieve that value as plain BOOL using -boolForKey: function in NSUserDefaults
To save:
[boolUserDefaults setObject:[NSNUmber numberWithBool:isQuiet] forKey:#"stringKey"];
When you read it back, read it as a NSNumber then do:
BOOL savedIsQuiet = [theNumberYouSaved boolValue];
Swift:
To save bool:
UserDefaults.standard.set(true, forKey: "storageKey")
To retrieve the bool:
let boolValue = UserDefaults.standard.bool(forKey: "storageKey")