How to save a high score - ios

How do I go about saving a high score using nsuserdefaults and displaying it on the main menu. Currently my score label code looks like this. BTW I am using objective c.
_scoreLabel.text = [NSString stringWithFormat:#"%02lu", (unsigned long)_enemies.count];

this is how you save the score
if(HighScore<ScoreNumber)
{
[[NSUserDefaults standardUserDefaults]setInteger:ScoreNumber forKey:#"Save"];
}
this is how you get the score,so you need to convert int to string..and display a string in a label.
HighScore=[[NSUserDefaults standardUserDefaults] integerForKey:#"Save"];

You can save your highScore using NSUserDefaults setInteger. The code for saving an integer into NSUserDefault goes here.
[[NSUserDefaults standardUserDefaults] setInteger:HighScore forKey:#"HighScore"];
Now you can set the highScore from NSUserDefault. The code for retrieving Integer from NSUserDefault goes here.
[_scoreLabel setText:[NSString stringWithFormat:#"%d", [[NSUserDefaults standardUserDefaults] integerForKey:#"HighScore"]]];

Related

How I can make NSUserDefaults for each user of my app?

I need make access to UserDefaults in my app. But I need save settings for each user, who was registered in app. For example:
[[NSUserDefaults standartUserDefaults] setObject:#"15:00" forKey:#"lastTime"]// for current user1
and after logout user1 and login user2:
[[NSUserDefaults standartUserDefaults] setObject:#"11:00" forKey:#"lastTime"]// for current user2
And, if I try read key #"lastTime", then I get the last value, but not for this user. I can store userDefaults in differentFiles, as an a variant? Or other solutions?
UPDATED:
Finally I solved this problem:
#define UserDefaults [NSUserDefaults standardUserDefaults]
#define uKey(key) [NSString stringWithFormat:#"%#_%#",key,User.user_name]
[UserDefaults setInteger:lastData forKey:uKey(#"lastResultDataId")];
There is no concept of users on iOS (yet). Each device, an iPhone or iPad, is presumed to have one and only one user. Obviously that's often not true, especially on an iPad, so some apps create schemes for different people to use the device. If you've done that -- and it's not clear that you have -- then you know the username. If you are writing a Mac app then use NSUserName() to get the name of the logged-in user. After that just concatenate the username onto the key from your NSUserDefaults, something like this:
NSString *username = #"john";
[[NSUserDefaults standardUserDefaults] setObject:#"15:00" forKey:[NSString stringWithFormat:#"last_login_username_%#", username]];
(username would set either to NSUserName() for a Mac app or whatever scheme you've come up for a multiuser iOS app)
If you have some kind of user identifier, use a dictionary for the different users:
NSDictionary *user = #{#"lastTime": #"15:00" };
[[NSUserDefaults standartUserDefaults] setObject:user forKey:#"userId"];
You have to have some way to uniquely identify the user, then just use whatever that is - UUID, username, email, userId - in the key when setting / getting the lastTime value
Personally I'd use a NSDictionary like and have a dictionary per user and store that into NSUserDefaults under a key constructed out of their username similar to below.
NSMutableDictionary *userDict = [[NSMutableDictionary alloc] init];
NSString *username = "myUsername";
NSDate *currentDateTime = [NSDate date];
[userDict setObject:username forKey:#"username"];
[userDict setObject:currentDateTime forKey:#"lastAccessed"];
/* Any other user date you want to store about this user
* Note we are going to use NSUserDefaults which is not
* secure so do not store sensitive data in here
*/
NSString *userDictKey = [NSString stringWithFormat:#"uk.co.yourAppName.%#", username];
[[NSUserDefaults standardUserDefaults] setObject:userDict forKey:userDictKey];
[[NSUserDefaults standartUserDefaults] synchronize];
And to retrieve this data all you'd need to do is know what the users username is and do
NSString *userDictKey = [NSString stringWithFormat:#"uk.co.yourAppName.%#", username];
NSDictionary *userRetrievedDict = [[NSUserDefaults standardUserDefaults] dictionaryForKey:userDictKey];
However if you want to make any amendments to this data you'll need to adapt it so that the data is moved into a NSMutableDictionary so you can update it and then store it back into NSUserDefaults
Make sure that after setting value, user going to synchronise the userdefaults.
like
[[NSUserDefaults standartUserDefaults] synchronize];

NSUserDefaults with time floats

I'm making a game in which the user must complete a task as quickly as possible, and I would like to display the user's best time and update the best time when he or she achieves a new one. I have:
float BestTimeValue
float starttime
-(void)start{
starttime += 0.001;
timelabel.text = [NSString stringWithFormat:#"%.3f", starttime];
}
if (starttime < BestTimeValue) {
[[NSUserDefaults standardUserDefaults] setObject:starttime forKey:[#"BestTimeValue"];
}
and in my viewdidload:
BestTimeValue = [[NSUserDefaults standardUserDefaults] objectForKey:#"BestTimeSaved"];
starttime stops when the game is over, but the value won't display in the label. Thanks!
You can't use a float with the setObject:forKey: and objectForKey: methods.
Use setFloat:forKey: and floatForKey:.
if (starttime < BestTimeValue) {
[[NSUserDefaults standardUserDefaults] setFloat:starttime forKey:[#"BestTimeValue"];
}
BestTimeValue = [[NSUserDefaults standardUserDefaults] floatForKey:#"BestTimeSaved"];
[[NSUserDefaults standardUserDefaults] setObject: forKey:] As the name says, it only accept object like NSString, NSNumber, NSDictionary, etc.
So you have to use other method [[NSUserDefaults standardUserDefaults] setFloat: forKey] or save the float in a NSNumber to use the setObjet Method [NSNumber numberWithFloat:thefloat];

Highscore Popup If New

I want to implement a simple concept. If the player gets a new highscore, there will be a sprite newHS that will become visible, otherwise it is hidden. Here is my code:
if (score < highScore) {
newHS.visible = NO;
}
else {
highScore = score;
[[NSUserDefaults standardUserDefaults] setInteger:highScore forKey:#"HighScore"];
[[NSUserDefaults standardUserDefaults]synchronize];
newHS.visible = YES;
}
However, I ran into a problem. If I start off by scoring 1, it pops up just fine. Then if I score 1 again it still pops up (because score is not less than highScore, it's the same), but I don’t want that because it’s not a NEW highscore anymore.. How would I get around this? I thought of adding another variable, something like “previousScore” or something but I am not sure how to approach this..
int highscore = [[NSUserDefaults standardUserDefaults] valueForKey:#"HighScore"];
if (score > highscore) {
newHS.visible = YES;
[[NSUserDefaults standardUserDefaults] setInteger:score forKey:#"HighScore"];
[[NSUserDefaults standardUserDefaults] synchronize];
}
else newHS.visible = NO;
You don't show us how or where you create the highscore integer, my guess is that you create a new local highscore int and set it to 0 instead of set it to the saved highscore.

How would I be able to save an integer when an app is terminated and then load it again once the app is reopened?

I am working on an app where I need to save one int until the player decides to play the game again. It would be greatly appreciated if someone could guide me by using NSUserDefaults to save this integer whenever the application is terminated, and then be able to load it again as soon as the application loads. If there is any further information that is needed to help you help me just let me know! Thanks in advance!
You cannot save an int, you will need to convert it to an NSNumber. Use:
NSNumber *number = #(myInt);
Then you can save it (when the app terminates in your appDelegate's applicationWillTerminate:) using:
[[NSUserDefaults standardUserDefaults] setObject:number forKey:#"number"];
[[NSUserDefaults standardUserDefaults] synchronize];
To retrieve the value use:
NSNumber *number = [[NSUserDefaults standardUserDefaults] stringForKey:#"number"];
As pranav told you can store int as NSNumber or you can store it as a String, Following will work fine with NSNumber object,
int a = 10;
NSNumber *myNumber = [NSNumber numberWithInt:a];
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
[defaults setObject:myNumber forKey:#"storedInt"];
NSLog(#"stored number object %#", [defaults objectForKey:#"storedInt"]); // retrieve value from NSUserDefaults
//then change NSNumber object to int value - if required
int retrievedInt = [myNumber intValue];
NSLog(#"int value %u", retrievedInt);

ios saving and retrieving NSNumber from NSUserdefaults

I've searched but I can't find a good explanation as to why I'm still not getting the right value from my saved Integer.
This is how I saved my event Id.
NSUserDefaults *prefs = [NSUserDefaults standardUserDefaults];
[prefs setInteger:eventSelected.eventId forKey:#"currentEvent"];
This is how I'm trying to retrieve it.
NSLog(#"user dfault %#", [NSNumber numberWithUnsignedInt:[[[NSUserDefaults standardUserDefaults] objectForKey:#"currentEvent"] unsignedIntegerValue]]);
I'm gettin gthis.
user dfault 123581200
Also, to note, event if I did intValue instead of unsignedIntegerValue , it would still give me a random id number. was wondering what I'm doing wrong.
NSUserDefaults *prefs = [NSUserDefaults standardUserDefaults];
// Convert your value to IntegerValue and Save it
[prefs setInteger:[eventSelected.eventId integerValue] forKey:#"currentEvent"];
// Dont forget to synchronize UserDefaults
[prefs synchronize];
// To Access this value
NSLog(#"%d",[prefs integerForKey:#"currentEvent"]);
Instead of this code NSLog(#"user dfault %#", [NSNumber numberWithUnsignedInt:[[[NSUserDefaults standardUserDefaults] objectForKey:#"currentEvent"] unsignedIntegerValue]]);
Use this
NSLog(#"user dfault %#", [[NSUserDefaults standardUserDefaults] integerForKey:#"currentEvent"]);
NSNumber give a pointer value, not integer value.
To retrieve the integer you should use below function:
[[NSUserDefaults standardUserDefaults] integerForKey:#"currentEvent"];
when you ask for objectForKey, it box it first and then return the object. Posting intValue will convert the address of that object into integer. Hence each time you will receive different number.
NSNumber *number;
store:
[[NSUserDefaults standardUserDefaults] setValue:number forKey:#"Number"];
retrieving:
number = [NSNumber numberWithInteger:[[NSUserDefaults standardUserDefaults] integerForKey:#"Number"]];

Resources