iOS - Retrieving and saving scores of a game - ios

I developed a small game , , so I manage something like this , when app lunches for the first time , it save the very first record , then after that it loads and compares the new records with the the first time record . but the problem is when user hit the record it should be saved the new record but it doesn't !!! and saves the first record again ! here is my code :
- (void)manageScores {
NSLog(#"managed");
NSString *tempScore = [NSString stringWithFormat:#"%#",scoreLabel.text];
GO.scoreNumber = [tempScore integerValue];
GO.bestScoreNumber = [tempScore integerValue];
GO.scores.text = [NSString stringWithFormat:#"score:%d",GO.scoreNumber];
GO.bestScore.text = [NSString stringWithFormat:#"best:%d",GO.bestScoreNumber];
if ([[NSUserDefaults standardUserDefaults] boolForKey:#"HasLaunchedOnce"])
{
// app already launched
NSLog(#"app already launched");
[GO loadBestScore];
}
else
{
[[NSUserDefaults standardUserDefaults] setBool:YES forKey:#"HasLaunchedOnce"];
[[NSUserDefaults standardUserDefaults] synchronize];
// This is the first launch ever
NSLog(#"first time lunch ever");
[GO saveBestScore];
}
if (GO.scoreNumber > GO.bestScoreNumber) {
//**************THIS METHOD DOESN'T WORK WHEN USER HIT THE RECORD*********/////
[GO saveBestScore];
//**************//
GO.scores.text = [NSString stringWithFormat:#"score:%d",GO.scoreNumber];
GO.bestScore.text = [NSString stringWithFormat:#"best:%d",GO.scoreNumber];
GO.shareScore.text = [NSString stringWithFormat:#"score:%d",GO.bestScoreNumber];
NSLog(#"new record");
}
if (GO.scoreNumber < GO.bestScoreNumber) {
GO.scores.text = [NSString stringWithFormat:#"score:%d",GO.scoreNumber];
GO.bestScore.text = [NSString stringWithFormat:#"best:%d",GO.bestScoreNumber];
GO.shareScore.text = [NSString stringWithFormat:#"score:%d",GO.bestScoreNumber];
[GO loadBestScore];
NSLog(#"NO NEW RECORD");
}
}
saving and loading scores (methods form GameOver.h/m (GO) )
- (void)saveBestScore {
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
[defaults setInteger:bestScoreNumber forKey:#"highScore"];
[defaults synchronize];
NSLog(#"BEST SCORE SAVED:%i",bestScoreNumber);
}
- (void)loadBestScore {
NSUserDefaults *prefs = [NSUserDefaults standardUserDefaults];
bestScoreNumber = (int)[prefs integerForKey:#"highScore"];
}

Looks like you should save scoreNumber rather than bestScoreNumber
Reason:
The following code wants to save the best score because GO.ScoreNumber > Go.BestScoreNumber.
if (GO.scoreNumber > GO.bestScoreNumber) {
//**************THIS METHOD DOESN'T WORK WHEN USER HIT THE RECORD*********/////
[GO saveBestScore];
//**************//
GO.scores.text = [NSString stringWithFormat:#"score:%d",GO.scoreNumber];
GO.bestScore.text = [NSString stringWithFormat:#"best:%d",GO.scoreNumber];
GO.shareScore.text = [NSString stringWithFormat:#"score:%d",GO.bestScoreNumber];
NSLog(#"new record");
}
But in saveBestScore, it stores bestScoreNumber, which is the previous highest score number.
[defaults setInteger:bestScoreNumber forKey:#"highScore"];

- (void)saveBestScore
This method doesn't take an argument, but it should.
If you're keeping scores as int, you should modify it to look like this:
- (void)saveBestScore:(int)bestScore
Then, on first launch, call saveBestScore with an argument of 0, just to get it initialize. In fact, if you write saveBestScore method correctly, you don't really need to check whether the app has already launched ever.
- (void)saveBestScore:(int)bestScore {
if (bestScore > [[[NSUserDefaults standardUserDefaults]
objectForKey:#"BestScore"] intValue]); {
[[NSUserDefaults standardUserDefaults] setObject:[NSNumber
numberWithInt:bestScore] forKey:#"BestScore"];
}
- (int)loadBestScore {
return [[[NSUserDefaults standardUserDefaults] objectForKey:#"BestScore]
intValue];
}

Related

call different method with same string in different value

I have two methods in my .m file .And i want to access by different values but in my Facebook variable gives nil value but if i use only one line and remove second line of object for key then it work fine for one method .
How i do this which work for my both methods
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
[[NSUserDefaults standardUserDefaults] synchronize];
user=[defaults objectForKey:#"userid"];
facebook=[defaults objectForKey:#"FACEBOOKprofile"];
facebook =[defaults objectForKey:#"VLCC"];
if ([facebook isEqualToString:#"VLCCFACEBOOK"])
{
[self FacebookRecord];
}
else if([facebook isEqualToString:#"VLCC"])
{
[self VlccRecord];
}
assume that
Choice-1
// for accessing the both condition in same time
Initially Store the UserDefault value based on your method.
if you are access with facebook , on that time store the string like
[[NSUserDefaults standardUserDefaults] setObject:"VLCCFACEBOOK" forKey:#"FACEBOOKprofile"];
[[NSUserDefaults standardUserDefaults] synchronize];
if you are access with VLCC , on that time store the string like
[[NSUserDefaults standardUserDefaults] setObject:"VLCC" forKey:#"VLCCprofile"];
[[NSUserDefaults standardUserDefaults] synchronize];
and retrieve the both and check like
if ([[[NSUserDefaults standardUserDefaults]
objectForKey:#"FACEBOOKprofile"]isEqualToString:#"VLCCFACEBOOK"])
{
[self FacebookRecord];
}
if([[[NSUserDefaults standardUserDefaults]
objectForKey:#"VLCCprofile"] isEqualToString:#"VLCC"])
{
[self VlccRecord];
}
Choice-2
// for accessing single condition on single time
if you are access with facebook , on that time store the string like
[[NSUserDefaults standardUserDefaults] setObject:"VLCCFACEBOOK" forKey:#"FACEBOOKprofile"];
[[NSUserDefaults standardUserDefaults] synchronize];
if you are access with VLCC , on that time store the string like
[[NSUserDefaults standardUserDefaults] setObject:"VLCC" forKey:#"FACEBOOKprofile"];
[[NSUserDefaults standardUserDefaults] synchronize];
and retrieve the both and check like
if ([[[NSUserDefaults standardUserDefaults]
objectForKey:#"FACEBOOKprofile"]isEqualToString:#"VLCCFACEBOOK"])
{
[self FacebookRecord];
}
else if([[[NSUserDefaults standardUserDefaults]
objectForKey:#"FACEBOOKprofile"] isEqualToString:#"VLCC"])
{
[self VlccRecord];
}
In your code, the [self VlccRecord] method will always get called because you are overwriting the facebook variable.
facebook=[defaults objectForKey:#"FACEBOOKprofile"];
facebook =[defaults objectForKey:#"VLCC"];
If you are looking to append the two strings : Then use the stringbyAppendingString method.
int a = 10;
a = 20;
print >> a; //20
int a = 10;
print1 >> a; //10
a = 20;
print2 >> a; //20
Here,
a = facebook;
print1 = [self FacebookRecord];
print2 = [self VlccRecord];
I believe you'll understand.

Saving Users Scores

Ola, I am trying to find a way to save user scores so when it is closed from the background it saves their scores and when open again it displays that score once again. By the way the thing Im saving is a tap counter so when they tap it has to add onto their previous score.
Any suggestions?
Save:
int numberOfTaps = 42; // some number of taps
NSUserDefaults *standardUserDefaults = [NSUserDefaults standardUserDefaults];
[standardUserDefaults setValue:[NSNumber numberWithInt:numberOfTaps] forKey:#"numberOfTaps"];
Retrieve:
NSUserDefaults *standardUserDefaults = [NSUserDefaults standardUserDefaults];
int savedTaps = [[standardUserDefaults objectForKey:#"numberOfTaps"] intValue];
Updating For Further Information
Just to make it extremely easy:
Copy these methods somewhere in your .m
- (void) saveNumberOfTaps:(int)numberOfTaps {
[[NSUserDefaults standardUserDefaults] setValue:[NSNumber numberWithInt:numberOfTaps] forKey:#"numberOfTaps"];
NSLog(#"Saved numberOfTaps: %i", numberOfTaps);
}
- (int) getNumberOfTaps {
if ([[[NSUserDefaults standardUserDefaults] objectForKey:#"numberOfTaps"] intValue]) {
int numberOfTaps = [[[NSUserDefaults standardUserDefaults] objectForKey:#"numberOfTaps"] intValue];
NSLog(#"Getting numberOfTaps: %i", numberOfTaps);
return numberOfTaps;
}
else {
NSLog(#"No taps saved yet");
return 0;
}
}
Then whenever you want to use these values, you can use the following:
// Save Taps
[self saveNumberOfTaps:14];
// Get Taps
int taps = [self getNumberOfTaps];
NSLog(#"taps retrieved: %i", taps);
It sounds like you're just starting out, so try using NSUserDefaults. Once you need something more advanced, look into Core Data.

NSUserDefaults if data equal to something then NSLog

I created a simple app when you click on a button it saves first click with 1 second with 1 and so. So, I tried to check if the first click equal to 1 then NSLog but it didn't worked.
Here's my code:
-(IBAction)add:(id)sender
{
//Once the user click on the button it adds 1
static int num = 0;
num+=1;
//Save the number for key "saved and the number" ex: if number is 1 so for key is "saved 1"
NSString *dataa = [NSString stringWithFormat:#"%i", num];
NSString *fkey = [NSString stringWithFormat:#"saved %i", num];
NSUserDefaults *def = [NSUserDefaults standardUserDefaults];
[def setObject:dataa forKey:fkey];
[def synchronize];
}
-(IBAction)load:(id)sender
{
//load the data forkey "saved 1" wich will be '1'
NSUserDefaults *def = [NSUserDefaults standardUserDefaults];
NSString *loadd = [def objectForKey:#"saved 1"];
NSLog(#"%#",loadd);
//and here I failed, here I want to check if [def objectForKey:#"saved 1"] == '1'
//then NSLog#"Yes" but it NSLogs "NOO"
NSString *no = #"1";
if(loadd == no){
NSLog(#"YES");
}else{
NSLog(#"NOO");
}
}
So what is the issue here?
Thanks in Advance
use [loadd isEqualToString:no] instead, that compares strings.
here is the documentation link

Method Called only After App Update

I have a Scenario , where i have to call a Method only once , whenever a User Will Update the Application or make a Fresh Install.
SO my Question is there is any particular Method to be called in App Delegate , After We update the Application , so if someone can tell me a another way to Achieve this , that would be really appreciated.
I would set a value in NSUserDefaults after you have called the function one time. See the accepted answer here: iOS : Call a method just one time
If you need to run after an update, you should include an always increasing number, or pull the build number, and check against the saved value. This will allow you to know if the app has been updated.
I am writing following function which uniquely checks if user has rated the current version, [self nowRate] is the function, please change this to whatever action you want to perform uniquely per version
-(void)rateApp {
NSString *version = [[[NSBundle mainBundle] infoDictionary] objectForKey:#"CFBundleShortVersionString"];
NSMutableDictionary*appRatedForVersion = [[NSMutableDictionary alloc] init];
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
if ([[[NSUserDefaults standardUserDefaults] dictionaryRepresentation].allKeys containsObject:#"AppRateDictionaryData"]){
NSData *versionRateData = [defaults objectForKey:#"AppRateDictionaryData"];
appRatedForVersion = [NSKeyedUnarchiver unarchiveObjectWithData:versionRateData];
if ([appRatedForVersion objectForKey:version] != nil) {
NSNumber *isAppRatedForCurrentVersion = [appRatedForVersion objectForKey:version];
BOOL hasBeenRated = [isAppRatedForCurrentVersion boolValue];
if (hasBeenRated) {
//Action already performed in this version do whatever you like
} else {
[self nowRate];
}
} else {
[appRatedForVersion setObject:[NSNumber numberWithBool:YES] forKey:version];
NSData *versionRateData1 = [NSKeyedArchiver archivedDataWithRootObject:appRatedForVersion];
[defaults setObject:versionRateData1 forKey:#"AppRateDictionaryData"];
[defaults synchronize];
[self nowRate];
}
} else {
[appRatedForVersion setObject:[NSNumber numberWithBool:YES] forKey:version];
NSData *versionRateData = [NSKeyedArchiver archivedDataWithRootObject:appRatedForVersion];
[defaults setObject:versionRateData forKey:#"AppRateDictionaryData"];
[defaults synchronize];
[self nowRate];
}
}

How to add to a saved NSUserDefault?

I am making a game in Xcode which in includes a scoring system in each level. Here I have some code that gets an NSString (passedValue1) by using a delegate.
Then i add the code to receive the value in my viewDidLoad and display my value in a UILabel
-(void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib
// Do any additional setup after loading the view, typically from a nib
NSString *key=#"labelKey";
if(passedValue1){
NSUserDefaults *prefs = [NSUserDefaults standardUserDefaults];
NSObject * object = [prefs valueForKey:key];
if(object != nil){
NSUserDefaults *defults = [NSUserDefaults standardUserDefaults];
[defults setValue:passedValue1 forKey:key];
[defults synchronize];
}
else{
NSUserDefaults *defults = [NSUserDefaults standardUserDefaults];
NSInteger readScore=[[[NSUserDefaults standardUserDefaults] valueForKey:key] integerValue];
NSInteger newValue=readScore+[passedValue1 integerValue];
[defults setValue:[NSString stringWithFormat:#"%d",newValue] forKey:key];
[defults synchronize];
}
}
label.text = [[NSUserDefaults standardUserDefaults]objectForKey:key];
}
Once I have displayed the value I then save it into a label using a NSUserDefault. However, once I have replayed my game and have another score value I would like to add the new passedValue1 value to the currently saved value...
For example:
say I play my level and I get the score value of 10. The value is then saved and I replay my level. I would then like to take the saved value and add it to the value i just scored. So thats say the second value I have scored is 20. I would then like my code to add them together and give me a value of 30.
can anyone help because the code I'm using does not correctly do the function that I want to do which is add the previous and the currently passed value.
What is wrong with my code??
Thanks in advance.
You shouldn't use valueForKey: for this (it's not what you might think it is, see Key-Value Coding). Instead, you should use objectForKey: or in your case integerForKey:.
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
NSInteger value = [defaults integerForKey:key];
value += [passedValue1 integerValue];
[defaults setInteger:value forKey:key];
BOOL success = [defaults synchronize];
It seems that you got your if condition wrong, it should be
if (object == nil) { // <-- you have object != nil here !
// save new value
} else {
// read old value, add something, save new value
}

Resources