The game that I am creating has a highScore integer variable that gets assigned when the player loses. I am using NSUsersDefaults class to save my high score. Here is my code that I am using:
-(void)saveScore {
[[NSUserDefaults standardUserDefaults] setInteger:score forKey:#"highScore"];
[defaults setInteger:score forKey:#"highScore"];
[defaults synchronize];
NSLog(#"High Score: %i ", highScore);
}
-(IBAction)buttonReleased:(id)sender {
[stopWatchTimer invalidate];
AudioServicesPlayAlertSound(kSystemSoundID_Vibrate);
NSString *label0 = #"Hold to Start";
[labelText setText:label0];
if (score > 0) {
score--;
}
else {
score = 0;
NSLog(#"Changed score to 0");
}
if (score > highScore) {
[self saveScore];
NSString *scoreMessage =[[NSString alloc] initWithFormat:#"Congrats! You have a new High Score! Click Share High Score to share your score of: %i",score];
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:#"High Score!" message:(NSString *)scoreMessage delegate:nil cancelButtonTitle:#"OK" otherButtonTitles: nil];
[alert show];
[alert release];
score = 0;
}
else {
NSString *scoreMessage =[[NSString alloc] initWithFormat:#"Game Over! Your score was: %i",score];
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:#"GAME OVER!" message:(NSString *)scoreMessage delegate:nil cancelButtonTitle:#"Try Again" otherButtonTitles: nil];
[alert show];
[alert release];
score = 0;
}
- (void)viewDidLoad
{
[super viewDidLoad];
int highscore = [[NSUserDefaults standardUserDefaults] integerForKey: #"highScore"];
[stopWatchTimer invalidate];
stopWatchTimer=nil;
}
I have been wrestling with this for HOURS! What am I doing wrong?! Note: Can you explain it as simply as possible.
Thanks!
-Matt
Reading it:
int highscore = [[NSUserDefaults standardUserDefaults] integerForKey: #"highScore"];
It will most likely be the default value of int (i.e. 0) when the file is blank.
Also don't forget to force a write of your defaults to "disk" with synchronize:
-(void)saveScore {
NSUSerDefaults *defaults = [NSUserDefaults standardUserDefaults];
[defaults setInteger:score forKey:#"highScore"];
[defaults synchronize];
}
You can load the highscore either in viewDidLoad or even in your init (or initWithNibName) method since this part isn't dependent on your view being loaded.
You could declare a property on your Scores view that you set in the viewDidLoad method. Alternatively you could expose the UILabel of that scores class (if that's what you use) as a property of your scores class.
- (void)viewDidLoad:
{
...
self.scoresView.textLabel.text = [NSString stringWithFormat:#"%d", highScore];
...
}
There is a really simple highscore management system which I have written it even has online support. You can find it https://github.com/faizanaziz/HighScore
Related
- (void)uploadTicket:(GDataServiceTicket *)ticket
finishedWithEntry:(GDataEntryYouTubeVideo *)videoEntry
error:(NSError *)error
{
NSLog(#"ticket");
UIButton *uploadButton = (UIButton *)[backgroundImage viewWithTag:10];
UIButton *cancleButton = (UIButton *)[backgroundImage viewWithTag:20];
if (error == nil)
{
// tell the user that the add worked
NSLog(#"Video Successfully Uploaded to Youtube");
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
NSNumber *uploadedToYouTube = [defaults objectForKey:#"uploadedToYouTube"];
if(nil == uploadedToYouTube)
{
[defaults setObject:[NSNumber numberWithBool:YES] forKey:#"uploadedToYouTube"];
[defaults synchronize];
}
NSNumber *userOpenedYoutubeView = [defaults objectForKey:#"userOpenedYoutubeToUnlockTheme"];
if(nil != userOpenedYoutubeView)
{
// [defaults setBool:NO forKey:#"Unlock_Theme"];
[defaults setObject:[NSNumber numberWithBool:NO] forKey:#"Unlock_Theme"];
[defaults synchronize];
UIAlertView *alrtView = [[UIAlertView alloc] initWithTitle:#"Congrats...!" message:#"Your new theme is Unlocked" delegate:self cancelButtonTitle:#"OK" otherButtonTitles:nil, nil];
[alrtView show];
[alrtView release];
[self removeFromSuperview];
}
else
{
UIAlertView *alrtView = [[UIAlertView alloc] initWithTitle:#"Success...!" message:#"Your Video is successfully uploaded to Youtube" delegate:self cancelButtonTitle:#"OK" otherButtonTitles:nil, nil];
[alrtView show];
[alrtView release];
[self removeFromSuperview];
}
}
else {
NSLog(#"Fails to upload Video to Youtube");
UIAlertView *alrtView = [[UIAlertView alloc] initWithTitle:#"Sorry" message:#"Fails to upload video to Youtube. Please try again" delegate:self cancelButtonTitle:#"OK" otherButtonTitles:nil, nil];
[alrtView show];
[alrtView release];
}
mProgressView . hidden = YES;
uploadButton . hidden = NO;
cancleButton . enabled = YES;
[mProgressView setProgress: 0.0];
[self setUploadTicket:nil];
}
Every time i try to upload it is showing alert message "failed to upload". I don't get why it is showing like that. Before upgrading to Xcode 7 it works fine. Anyone know please help me.
sorry if the title is a bit sloppy or confusing, I'll try to explain it a bit more detailed.
I have a function in my app which allows users to only use it 10 times a day. The code below handles the counting per day which is actually working good except that the user always have to press twice on a new loop before it's getting called.
I think it has something to do with the fabs function, or what could be the reason the user has to press twice on a new loop?
-(void)dailyCount:(id)sender{
NSString *kFirstLaunchDateKey = #"tenPerDay";
NSDate *firstLaunchDate = [[NSUserDefaults standardUserDefaults] objectForKey:kFirstLaunchDateKey];
NSInteger count = [[NSUserDefaults standardUserDefaults] integerForKey:#"perDay"];
if (!firstLaunchDate) {
[[NSUserDefaults standardUserDefaults] setObject:[NSDate date] forKey:kFirstLaunchDateKey];
[[NSUserDefaults standardUserDefaults] setInteger:count+1 forKey:#"perDay"];
return;
}
NSTimeInterval diff = fabs([firstLaunchDate timeIntervalSinceNow]);
if (diff > 60 * 60 * 24 * 1) {
[[NSUserDefaults standardUserDefaults] removeObjectForKey:#"tenPerDay"];
[[NSUserDefaults standardUserDefaults] removeObjectForKey:#"perDay"];
}else{
if (count % 11 == 0) {
[UIAlertView showWithTitle:#"Daily Limit Exceeded"
message:#"Sorry, you can use this option only 10 times per day."
cancelButtonTitle:#"Ok"
otherButtonTitles:nil
tapBlock:^(UIAlertView *alertView, NSInteger buttonIndex) {
if (buttonIndex == [alertView cancelButtonIndex]) {
}
}];
}else {
// do something here... (Have to press twice on a new loop before it's getting called)
[[NSUserDefaults standardUserDefaults] setInteger:count+1 forKey:#"perDay"];
[[NSUserDefaults standardUserDefaults] synchronize];
}
}
}
-(void)dailyCount:(id)sender{
NSString *kFirstLaunchDateKey = #"tenPerDay";
NSDate *firstLaunchDate = [[NSUserDefaults standardUserDefaults] objectForKey:kFirstLaunchDateKey];
if (!firstLaunchDate) {
[[NSUserDefaults standardUserDefaults] setObject:[NSDate date] forKey:kFirstLaunchDateKey];
[[NSUserDefaults standardUserDefaults] setInteger:0 forKey:#"perDay"];
[[NSUserDefaults standardUserDefaults] synchronize];
[self counterNew];
return;
}
NSTimeInterval diff = fabs([firstLaunchDate timeIntervalSinceNow]);
if (diff > 60 * 60 * 24 * 1) {
[[NSUserDefaults standardUserDefaults] removeObjectForKey:#"tenPerDay"];
[[NSUserDefaults standardUserDefaults] setInteger:0 forKey:#"perDay"];
[[NSUserDefaults standardUserDefaults] synchronize];
[self counterNew];
}else{
[self counterNew];
}
}
-(void)counterNew{
NSInteger count = [[NSUserDefaults standardUserDefaults] integerForKey:#"perDay"];
if (count > 10) {
[UIAlertView showWithTitle:#"Daily Limit Exceeded"
message:#"Sorry, you can use this option only 10 times per day."
cancelButtonTitle:#"Ok"
otherButtonTitles:nil
tapBlock:^(UIAlertView *alertView, NSInteger buttonIndex) {
if (buttonIndex == [alertView cancelButtonIndex]) {
}
}];
}else {
//Do something here...
[[NSUserDefaults standardUserDefaults] setInteger:count+1 forKey:#"perDay"];
[[NSUserDefaults standardUserDefaults] synchronize];
}
}
The photo in the link below illustrates the app I am currently working on, the name is a UITextfield that the user edits him/herself and the balance is label in which the user clicks the add button to add their desired funds. Then the two textfields below that allow for the input of money spent and how it was spent, this is then saved as a UITableviewCell in the UITable view. The problem I am currently having right now is when I restart my iPhone device the previously inputted data is rested meaning the user will have to rewrite everything which wouldn't help as this is an app to monitor one's savings. I did some googling to see if there was a fix for this I came across NSUserDefaults and tried the following code in my viewDidLoad.
Could someone provide the steps for a different approach to keep the inputted information where it is even after the user turns off his or her iPhone/iPad etc. Heres the photo link
http://imgur.com/DceJ7gs
[[NSUserDefaults standardUserDefaults] synchronize];
This is the code I am using to add funds which in turn changes the balance displayed by the uilabel Balance in the above photo
- (IBAction)addFunds:(id)sender {
UIAlertView *alert = [[UIAlertView alloc]initWithTitle:#"Add Funds" message:#"Please add your funds" delegate:self cancelButtonTitle:#"Cancel" otherButtonTitles:#"Done", nil];
alert.alertViewStyle = UIAlertViewStylePlainTextInput;
[_inputStatement resignFirstResponder];
[_spent resignFirstResponder];
[myTableView resignFirstResponder];
[_custName2 resignFirstResponder];
[alert show];
}
- (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex{
//alertview input text was blank so we are doing a check
if([[alertView textFieldAtIndex:0].text isEqual:#""] && buttonIndex == 1){
UIAlertView *alert = [[UIAlertView alloc]initWithTitle:#"Input Required" message:#"Please fill in the textfield" delegate:self cancelButtonTitle:#"Ok" otherButtonTitles:nil, nil];
[alert show];
} else {
if(buttonIndex == 1){
NSString *tempText = [alertView textFieldAtIndex:0].text;
float toAdd = [tempText floatValue];
float add = [_currentBalance.text floatValue];
if(toAdd < 0) {
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:#"Error" message:#"You can't add a negative number, try again" delegate:nil cancelButtonTitle:#"Ok" otherButtonTitles:nil];
[alert show];
} else {
add = add + toAdd;
if(add >= 99999999.50){
UIAlertView *alert = [[UIAlertView alloc]initWithTitle:#"Well you broke it" message:#"You are not allowed to input this much. In the event you do have these funds, I apologize for putting in this restriction. Personally contact me at thejobemuhammed#gmail.com for further inquiries." delegate:self cancelButtonTitle:#"Ok" otherButtonTitles:nil, nil];
[alert show];
} else {
_currentBalance.text = [NSString stringWithFormat:#"%.2f", add];
if(!array){
array = [[NSMutableArray alloc]init];
}
NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
[dateFormatter setDateStyle:NSDateFormatterMediumStyle];
[dateFormatter setTimeStyle:NSDateFormatterNoStyle];
date1 = [NSDate dateWithTimeIntervalSinceNow:5];
NSString *resultString = [dateFormatter stringFromDate:date1];
[array insertObject:[NSString stringWithFormat:#"%#%#%#",#"$",tempText, #" deposited"] atIndex:0];
[date insertObject:resultString atIndex:0];
[details insertObject:#"This is a deposit" atIndex:0];
NSIndexPath *indexPath = [NSIndexPath indexPathForRow:0 inSection:0];
[self.myTableView insertRowsAtIndexPaths:#[indexPath] withRowAnimation:UITableViewRowAnimationAutomatic];
}
}
}
[_inputStatement resignFirstResponder];
[_spent resignFirstResponder];
[myTableView resignFirstResponder];
}
add this code where you want to save . i am not getting where are you saving .
save it using this code
NSString *valueToSave = #"hereis yourvalue";
[[NSUserDefaults standardUserDefaults] setObject:valueToSave forKey:#"preferencekyename"];
[[NSUserDefaults standardUserDefaults] synchronize];
to get it back later using this code
NSString *savedValue = [[NSUserDefaults standardUserDefaults]
stringForKey:#"preferencekyename"];
I have written a UIAlertView code with a textField and I want to write a code to store whatever is typed by the user as a pushable detail list. How can I do that?
- (IBAction)NewReference:(id)sender {
UIAlertView *newreference = [[UIAlertView alloc] initWithTitle:#"New Reference" message:#"Enter Name" delegate:self cancelButtonTitle:#"Cancel" otherButtonTitles: #"Done",nil];
newreference.alertViewStyle = UIAlertViewStylePlainTextInput;
[newreference textFieldAtIndex:0].delegate = self;
[newreference show];
}
Here you go good sir. Per your comment above, if you want to store data for NSUserDefaults here is how you would do it:
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
NSString* saveData = [[newreference textFieldAtIndex:0] text];
[defaults setObject:saveData forKey:#"whatever key you want here"];
[defaults synchronize];
Then to invoke or call it:
NSString* recallData = [defaults objectForKey:#"whatever key you named above"];
Happy coding -
I am creating a Disclaimer that will be shown when the user first launches the app. The disclaimer is an alertView with 2 option. If user agrees then firstViewController will display. If he doesn't he will be redirected to another viewController. But I can't get the disclaimer to disappear if the user agrees the first time. It is shown every time the app launches. Any help would be appreciated. Thank you in advance..
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
if (![[defaults valueForKey:#"keyDisclaimer"] isEqualToString:#"accepted"]) {
UIAlertView *disclaimer = [[UIAlertView alloc] initWithTitle:#"Read Before use" message:#"By using this app you agree to its terms and conditions.\n\n\n\n\n\n\n\n\n\n\ntext heren\n\n\n\n\n\n\n\n\n\n\n\n\n" delegate:self cancelButtonTitle:#"No!" otherButtonTitles:#"Yes Let me In", nil];
[disclaimer show];
}
// Override point for customization after application launch.
return YES;
}
-(void) alertView:(UIAlertView *) alertView clickedButtonAtIndex:(NSInteger)buttonIndex{
NSString *buttonString = {[alertView buttonTitleAtIndex:buttonIndex]};
if ([buttonString isEqualToString:#"Yes Let me In"]) {
NSMutableDictionary* defaultValues = [NSMutableDictionary dictionary];
[defaultValues setValue:#"accepted"forKey:#"keyDisclaimer"];
[[NSUserDefaults standardUserDefaults] registerDefaults:defaultValues];
}
else if ([buttonString isEqualToString:#"No!"]) {
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:#"Sorry!" message:#"You are not allowed to use this app due to the fact that you did not agree to the terms and Conditions. Please exit this app!" delegate:self cancelButtonTitle:#"OK" otherButtonTitles:nil, nil];
[alert show];
// [[NSUserDefaults standardUserDefaults] setValue:#"notAccepted" forKey:#"keyDisclaimer"];
}
if ([buttonString isEqualToString:#"OK"]) {
introViewController *intro = [[introViewController alloc] initWithNibName:#"introViewController" bundle:nil];
_window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
_window.rootViewController = intro;
[_window makeKeyAndVisible];
}
}
NSMutableDictionary* defaultValues = [NSMutableDictionary dictionary];
[defaultValues setValue:...forKey:...]
[[NSUserDefaults standardUserDefaults] registerDefaults:defaultValues];
This will register your defaults if they are not set (for the first time)
Also, seems like you're forgetting [defaults synchronize] to commit changes after setting values. If so, you don't need the registerDefaults method at all.
Like this:
if ([buttonString isEqualToString:#"Yes Let me In"]) {
NSUserDefaults* defaults = [NSUserDefaults standardUserDefaults];
[defaults setValue:#"accepted"forKey:#"keyDisclaimer"];
[defaults synchronize];
}
You want to use something like stringForKey or objectForKey instead of valueForKey.
if([[defaults stringForKey:#"keyDisclaimer"] isEqualToString:#"accepted"]) {
I've had bad experiences with valueForKey in the past not always working the way I want. That might be what's causing you some problems.