문제

I'm trying to use NSUserDefaults to save two variables after app shutdown. One being firstBoot and the other showAgain. Prepare for bad code-

- (void)viewDidLoad
{
    [super viewDidLoad];

    NSUserDefaults *defaults1 = [NSUserDefaults standardUserDefaults]; //Here is where it is supposed to be loading the firstBoot variable to check whether or not it is the first boot
    NSInteger boot = [defaults1 integerForKey:@"firstBoot"];
    firstBoot = boot; //Sort of pointless variable swapping

    if (firstBoot == 0) //Detects if isn't first boot, checks whether or not showAgain is yes or no (1=yes, 0=no)
    {
        NSUserDefaults *defaults1 = [NSUserDefaults standardUserDefaults];
        NSInteger boot = [defaults1 integerForKey:@"firstBoot"];
        NSUserDefaults *defaults2 = [NSUserDefaults standardUserDefaults];
        NSInteger show = [defaults2 integerForKey:@"showAgain"];
        firstBoot = boot; //More var swapping
        showAgain = show; //^^
    }
    else
    {
        firstBoot = 1; //If it is the first boot, or the variable wasn't 0, it sets them both to 1.
        showAgain = 1;
    }
    if ((firstBoot == 1) || (showAgain == 1)) //Checks if its the firstBoot or showAgain is set to yes
    {
        UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Check the 'About' tab for help!" //Displays alert
                                                message:@""
                                               delegate:self
                                      cancelButtonTitle:@"Don't show again"
                                      otherButtonTitles:@"OK", nil];
        [alert show];
    }
    else
    {
        UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"firstboot and showagain != 1" //Displays alert if it isn't the first boot, or isn't 1 and showAgain isn't set to yes(1).
                                                    message:@""
                                                   delegate:self
                                          cancelButtonTitle:@"wrong"
                                          otherButtonTitles:@"OK", nil];
        [alert show];
    }
}

Alert-

- (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex {
    if (buttonIndex == [alertView cancelButtonIndex]) 
    {
        showAgain = 0; //If user clicks "Don't show again", set showAgain to off(0) and tell it it isn't the first boot anymore
        firstBoot = 0;

        NSUserDefaults *defaults1 = [NSUserDefaults standardUserDefaults];
        [defaults1 setInteger:0 forKey:@"firstBoot"]; //Hopefully stores firstBoot as 0
        [defaults1 synchronize];

        NSUserDefaults *defaults2 = [NSUserDefaults standardUserDefaults];
        [defaults2 setInteger:0 forKey:@"showAgain"]; //Again storing showAgain as 0
        [defaults2 synchronize];
    }
}

The first alert should pop up the very first time you run the app, while the second one is a debugger placeholder, and should run every time after the first time. For me, the second one is running first, telling me that firstBoot and showAgain != 1.

도움이 되었습니까?

해결책

NSInteger boot = [defaults1 integerForKey:@"firstBoot"]; will return 0 until you have saved a value in your defaults. 0, NO or nil are returned for keys that don't have any values stored.

The correct way to handle this is to register default values before you try to retrieve these user defaults.

// register default values. until you save your own value "firstBoot" will return YES
// you should put these two lines in the `application:didFinishLaunchingWithOptions:`
// method of the AppDelegate. Add all userdefaults that should have default values there
NSDictionary *defaultUserDefaults = @{ @"firstBoot" : @YES };
[[NSUserDefaults standardUserDefaults] registerDefaults:defaultUserDefaults];

// use BOOL instead of integer
BOOL firstBoot = [[NSUserDefaults standardUserDefaults] boolForKey:@"firstBoot"];
if (firstBoot) {
    NSLog(@"first launch");
    [[NSUserDefaults standardUserDefaults] setBool:NO forKey:@"firstBoot"];
    [[NSUserDefaults standardUserDefaults] synchronize]; 
}
else {
    NSLog(@"has been launched before");
}

다른 팁

How would firstBoot be set to YES on the first boot? Who would have set it?

Call registerDefaults: at the start of the application for all properties that should have values different from 0 before they have been explicitely set. For example, with a key firstBoot = YES. Alternatively, use a property "notFirstBoot" where the return value for missing properties ("NO") is what you actually want.

And there is really no need to call standardUserDefaults again and again.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top