Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

NSUserDefaults not updating value quickly

I have at timeout feature where if the app is idle (in background) for a period of time, I timeout my app and send the user to the login screen. I set the "timedOut" key in user defaults to YES in my application delegate, then reference that key in each view controller, where if it is YES, I segue to the login screen. On the login screen I have a label that displays "Session has timed out" if the "timedOut" is YES. My issue is that if I login, then logout very quickly, the label is displayed, even though I explicitly set that key to NO right after I show the label and then synchronize the user defaults. If I wait a second or two and logout, the label is hidden like it should be. I have solved the "problem", but would like to understand the behavior.

Code from view did load in my login view controller. You would think this changes the isTimedOut to NO, but when I do a quick logout viewdidload is called again, but isTimedOut is YES.

NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
sessionLabel.hidden = YES;
isTimedOut = [defaults boolForKey:@"isTimedOut"];
if (isTimedOut == YES)
{
    sessionLabel.hidden = NO;
    defaults = [NSUserDefaults standardUserDefaults];
    [defaults setBool:NO forKey:@"isTimedOut"];
    isTimedOut = NO;
    NSLog(@"Timed Out has been reset to %s",[defaults boolForKey:@"isTimedOut"] ? "YES" : "NO");
    [defaults synchronize];

}

UPDATE

I replaced the code above using a property in my app delegate instead of NSUserDefaults and the "strange" behavior went away.

eONavAppDelegate *appDelegate = [[UIApplication sharedApplication] delegate];
isTimedOut = appDelegate.isTimedOut;
sessionLabel.hidden = YES;
//isTimedOut = [defaults boolForKey:@"isTimedOut"];
  NSLog(@"Timed Out has been reset to %s",appDelegate.isTimedOut ? "YES" : "NO");
if (isTimedOut == YES)
{
    appDelegate.isTimedOut = NO;
    sessionLabel.hidden = NO;

}

MORE CODE

To logout, I have UIButtonBarItem calling a segue programmatically. The doLogout property tells the login view controller to run a logout API.

- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
// Make sure your segue name in storyboard is the same as this line
if ([[segue identifier] isEqualToString:@"logoutSegue"])
{

    // Get reference to the destination view controller
    eoLoginViewController *vc = [segue destinationViewController];
    vc.doLogout = YES;

}
} 

isTimedOut is set in one location in the app delegate.

-(void)timeoutWithDate:(NSDate *)currentDate
{
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
NSDate *previousDate  = [defaults objectForKey:@"enteredBackground"];
NSTimeInterval distanceBetweenDates = [currentDate timeIntervalSinceDate:previousDate];//TimeInterval is in seconds
NSLog(@"Time between dates in seconds %f",distanceBetweenDates);

double minutesInAnHour = 60;
double minutesBetweenDates = distanceBetweenDates / minutesInAnHour;
NSLog(@"minutesBetweenDates %f",minutesBetweenDates);


if(minutesBetweenDates > 60)
{
    isTimedOut = YES;

}
else
{
    isTimedOut = NO;
}

}
like image 497
Nate Avatar asked Nov 25 '25 19:11

Nate


1 Answers

Use this:

To save a Bool:

[[NSUserDefaults standardUserDefaults] setBool:NO forKey:@"isTimedOut"];

To Load a Bool:

    if ([[NSUserDefaults standardUserDefaults] boolForKey:@"isTimedOut"] == YES) {
        //it equals yes
        }

    else {
        //it equals no
        }
like image 181
OnkaPlonka Avatar answered Nov 28 '25 17:11

OnkaPlonka



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!