I have an integer stored in user defaults for my game's high score. Every time I start the game I want to check if the score is bigger than the previous high score, so I do this:
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
[defaults setInteger:highScoreNum forKey:#"highScoreNumber"];
if (highScoreNum <= score) {
highScoreNum = score;
SKLabelNode *highLabel = (SKLabelNode *)[self childNodeWithName:#"highLabel"];
highLabel.text = [NSString stringWithFormat:#"%ld", (long)highScoreNum];
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
[defaults setInteger:highScoreNum forKey:#"highScoreNumber"];
}
else if (highScoreNum > score) {
SKLabelNode *highLabel = (SKLabelNode *)[self childNodeWithName:#"highLabel"];
highLabel.text = [NSString stringWithFormat:#"%ld", (long)highScoreNum];
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
[defaults setInteger:highScoreNum forKey:#"highScoreNumber"];
}
and at the place where I declare the variable I do this:
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
[defaults setInteger:highScore forKey:#"highScoreNumber"];
highLabel.text = [NSString stringWithFormat:highScore];
but I always get 0 in highScoreNum.
Every time you do this...
[defaults setInteger:highScore forKey:#"highScoreNumber"];
...you send the highScore variable to the defaults. If you declare highScore, but then don't fetch a previously saved default (or don't otherwise initialize highScore), then it makes sense why you keep seeing zero here. You probably keep sending nil to the defaults, which go in (and come back out) as an integer value of zero.
Immediately after you declare *defaults, instead of calling setInteger:forKey, you probably want to have highScore store the appropriate value from the defaults, which looks like this:
highScore = [defaults integerFromKey:#"highScoreNumber"];
Also, don't forget to [defaults synchronize] when appropriate.
setInteger:forKey::
Sets the value of the specified default key to the specified integer
value.
So your code stores a value to the NSUserDefaults, in several places. It never reads a value back.
(and you should look up -synchronize)
Try this
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
[defaults setInteger:highScoreNum forKey:#"highScoreNumber"];
[defaults synchronize]; // force the upgrade NSUserDefaults
if (highScoreNum <= score) {
highScoreNum = score;
SKLabelNode *highLabel = (SKLabelNode *)[self childNodeWithName:#"highLabel"];
highLabel.text = [NSString stringWithFormat:#"%ld", (long)highScoreNum];
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
[defaults setInteger:highScoreNum forKey:#"highScoreNumber"];
}
else if (highScoreNum > score) {
SKLabelNode *highLabel = (SKLabelNode *)[self childNodeWithName:#"highLabel"];
highLabel.text = [NSString stringWithFormat:#"%ld", (long)highScoreNum];
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
[defaults setInteger:highScoreNum forKey:#"highScoreNumber"];
[defaults synchronize]; // force the upgrade NSUserDefaults
}
Related
I want to save high score using
synchronize
in my app,but i get gibberish number. Here what i got :
GameScene.m
if (highScore <score) {
highScore = score;
NSUserDefaults *prefs = [NSUserDefaults standardUserDefaults];
[prefs setInteger:highScore forKey:#"highScore"];
[[NSUserDefaults standardUserDefaults] synchronize];
}
GameOver.m
NSUserDefaults *prefs =[NSUserDefaults standardUserDefaults];
NSString *rezult =[prefs stringForKey:#"highScore"];
SKLabelNode *highscorelabel = [SKLabelNode labelNodeWithFontNamed:#"Menlo-Bold"];
highscorelabel.text =[NSString stringWithFormat:#"%ld",(long)rezult];
highscorelabel.position = CGPointMake(CGRectGetMidX(self.frame), 280);
highscorelabel.fontSize = 45;
highscorelabel.zPosition = 5;
[self addChild:highscorelabel];
Why I'm getting wrong value and how to fix this problem?
You're getting a wrong value because rezult is a NSString, you should change this:
NSString *rezult =[prefs stringForKey:#"highScore"];
to this:
NSInteger rezult = [prefs integerForKey:#"highScore"];
try to don't init another nsuserdefaults every time just use
[[NSUserDefaults standardUserDefaults] setValue:surname.text forKey:#"Nume"]; to write
[[NSUserDefaults standardUserDefaults] valueForKey:#"Name"] to read
AND MAKE SURE YOU USE THE SAME OBJECT TYPE!
I am making a small game for iOS in Xcode. In my game, tapping on a dot will give you one point. I am trying to make it so that if your score is higher than the first high score(0), it should save that and display the new high score. And the next score can beat that, and so on. Please give a thorough explanation because I am new to xCode and I am a 12 year old app developer.
If your do not find your score data important or sensitive use NSUserDefaults
First scene: (Setting the integer)
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
[defaults setInteger:yourHighScore forKey:#"HighScore"];
Other scenes: (Getting the integer)
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
yourHighScore = [defaults integerForKey:#"HighScore"]
Or same scene setting the yourHighScore value: (Getting the integer)
-(void)viewDidLoad {
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
yourHighScore = [defaults integerForKey:#"HighScore"]
}
NSInteger HighScore;
int Score;
IBOutlet UILabel *Show;
-(void)ViewDidLoad
{
[super viewDidLoad];
HighScoreNumber = [[NSUserDefaults standardUserDefaults] integerForKey:#"HighScoreSaved"];
}
-(void)ShowHighScore
{
if (Score > HighScore) {
HighScore = Score;
[[NSUserDefaults standardUserDefaults] setInteger:HighScore forKey:#"HighScoreSaved"];
}
Show.text = [NSString stringWithFormat:#"%li", HighScore];
}
I have two completely separate tasks being carried out but somehow they seem to connect.
In ViewController 1, I have:
NSString *foo = #"foo";
NSUserDefaults *default1 = [NSUserDefaults standardUserDefaults]
[default1 setObject:foo forKey:#"foo"];
[default1 synchronize];
and when I do:
NSLog(#"%#", [[NSUserDefaults standardUserDefaults] objectForKey:#"foo"]);
The value printed is what I expect it to be.
In ViewController 2, I have:
NSString *bar = #"bar";
NSUserDefaults *default2 = [NSUserDefaults standardUserDefaults]
[default2 setObject:bar forKey:#"bar"];
[default2 synchronize];
And same again when I NSLog it, the value is what I expect it to be.
But somehow when i try to print object #"foo" again it gives me the value for the second object, in this case #"bar"
Any guidance on why my original value is being overridden by the second value even tough the variable/key names are different in the 2 classes?
You are doing this for both:
[foo setObject:bar forKey:#"bar"];
Shouldn't it be:
[defaults1 setObject:foo forKey:#"foo"];
And
[defaults2 setObject:bar forKey:#"bar"];
There is however, a greater problem:
NSString *foo = #"foo";
NSUserDefaults *default1 = [NSUserDefaults standardUserDefaults];
[default1 setObject:foo forKey:#"foo"];
[default1 synchronize];
NSLog(#"%#", [[NSUserDefaults standardUserDefaults] objectForKey:#"foo"]);
NSString *bar = #"bar";
NSUserDefaults *default2 = [NSUserDefaults standardUserDefaults];
[default2 setObject:bar forKey:#"bar"];
[default2 synchronize];
NSLog(#"%#", [[NSUserDefaults standardUserDefaults] objectForKey:#"bar"]);
Will work properly, however you're creating defaults1 and defaults2 which are both instances of standard defaults, so:
NSUserDefaults * defaults1 = [NSUserDefaults standardUserDefaults];
NSUserDefaults * defaults2 = [NSUserDefaults standardUserDefaults];
[NSUserDefaults standardUserDefaults];
Are all pointers to the standardUserDefaults singleton. So they are identical instances. You could simply do:
NSUserDefaults *standardDefaults = [NSUserDefaults standardUserDefaults];
NSString *foo = #"foo";
[standardDefaults setObject:foo forKey:#"foo"];
NSString *bar = #"bar";
[standardDefaults setObject:bar forKey:#"bar"];
[standardDefaults synchronize];
NSLog(#"%#", [[NSUserDefaults standardUserDefaults] objectForKey:#"foo"]);
NSLog(#"%#", [[NSUserDefaults standardUserDefaults] objectForKey:#"bar"]);
You can print out the entire set of user defaults with code like this
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
NSDictionary *dictionary = [defaults dictionaryRepresentation];
NSLog( #"%#", dictionary );
Note that Apple puts lots of garbage in the user defaults, so you'll have to scroll to the end to see foo and bar. I'm guessing that you have a typo in code that you haven't shown us, and either foo is being overwritten, or foo simply isn't being displayed properly.
The current code in your question (after 1 edit) is all good and should work correctly.
How to save my games highscore in cocos2d, i already have a variable called score which displays the score while playing the game and i would like the variable for highscore to be "highscore", how do i code this into my game? UPDATE i have attempted to add it in but still no luck, here is the code in my init
UserHighScoreLabel = [[defaults valueForKey:#"highscore"] integerValue];
UserHighScoreLabel = [CCLabelTTF labelWithString:#"0" fontName:#"Arial" fontSize:14];
UserHighScoreLabel.position = ccp(65, 200);
UserHighScoreLabel.color = ccc3(255, 255, 255);
[self addChild:UserHighScoreLabel];
defaults = [NSUserDefaults standardUserDefaults];
[[NSUserDefaults standardUserDefaults]setInteger:Strategyscore forKey:#"highscore"];
[defaults synchronize];
You can use NSUserDefaults to save the high score on the device so it can retrieved at any time.
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
//saving
[defaults setValue:yourHighScore forKey:#"SavedHighScore"];
[defaults synchronize]; //you must synchronize to save
//retreiving
int highScore;
highScore = [[defaults valueForKey:#"SavedHighScore"] intValue];
//set label text to retrieved high score
UserHighScoreLabel.text = [NSString stringWithFormat:#"%d", highScore];
You could also store a JSON or XML string as the user default and parse it once you retreive it.
If you have a HighScore object or you are storing a lot of values, CoreData may be worth using, but it is not optimal if you are simply storing a few high scores.
EDIT with your code
defaults = [NSUserDefaults standardUserDefaults];
highScore = [[defaults valueForKey:#"SavedHighScore"] intValue];
//init before setting the text
UserHighScoreLabel = [CCLabelTTF labelWithString:#"0" fontName:#"Arial" fontSize:14];
//set label text to retrieved high score
UserHighScoreLabel.text = [NSString stringWithFormat:#"%d", highScore];
UserHighScoreLabel.position = ccp(65, 200);
UserHighScoreLabel.color = ccc3(255, 255, 255);
[self addChild:UserHighScoreLabel];
Firstly fetch your last high score.
int highScore = [[defaults valueForKey:#"highscrore"] integerValue];
Now compare it with last high score if it's higher than old store then new highscore.
[NSUserDefaults standardUserDefaults]setInteger:score forKey:#"highscrore"];
[defaults synchronize];
Hi I am using uislider and get the values in label. now i try to save the slider values. I don't know how to do this. If anybody knows please share the code. This is my code for slider changed.
-(IBAction)sliderChanged:(id)sender
{
UISlider *slider = (UISlider *)sender;
if((int)slider.value % 10 == 0)
{
sliderLabel.text = [[NSString alloc] initWithFormat:#"Value of:%d", (int)slider.value];
}
}
You can use NSUserDefault for storing the slider value.
NSUserDefaults* defaults = [NSUserDefaults standardUserDefaults];
[defaults setObject:sliderLabel.text forKey:#"Slider"];
[defaults synchronize];
You can retrieve the data like:
NSUserDefaults* defaults = [NSUserDefaults standardUserDefaults];
NSString *strValue = [defaults objectForKey:#"Slider"];
myLabel.text = strValue != nil ? strValue : #"No Value";
The above code is saving the sliderLabel to the NSUserDefault. If you want to store the slider value in the form of float then use:
[defaults setObject:[NSNumber numberWithFloat:slider.value] forKey:#"Slider"];
Retreive it like:
NSNumber *strValue = [defaults objectForKey:#"Slider"];
NSUserDefaults* defaults = [NSUserDefaults standardUserDefaults];
[defaults setObject:[NSNumber numberWithFloat:slider.value] forKey:#"sliderValue"];
I believe you should store the value as a float (the original type for a UISlider value), it's just cleaner, and you'll probably want to reuse the float value to set back your slider when reopening the screen with something like:
NSUserDefaults* defaults = [NSUserDefaults standardUserDefaults];
[self.slider setValue:[[defaults objectForKey#"sliderValue"] floatValue]];