NSUserDefaults does not update the value quickly

I have a timeout feature where if an app is inactive (in the background) for a certain period of time, I will timeout the app and send the user to the login screen. I set the timedOut key to the user defaults of YES in my application sub and then reference this key in every view controller where if it is YES I go to the login screen. On the login screen, I have a label that displays "Session Timeout" if "timedOut" is "YES". My problem is that if I log in and then log out very quickly, the shortcut will be displayed, although I explicitly set that key to NO right after I show the shortcut and then sync the custom defaults.If I wait for a second or second and log out, the shortcut is hidden as it should. I solved the "problem" but would like to understand the behavior.

The code from the view has loaded in my login controller. You might think this changes isTimedOut to NO, but when I do a quick logout the 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 by using a property in my application sub instead of NSUserDefaults, and the "weird" behavior disappeared.

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 log out, I have a UIButtonBarItem calling segue programmatically. The doLogout property instructs the login controller to run the 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 place in the application 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;
}

}

      

+3


source to share


2 answers


Use this:

To save Bool:

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

      



To load Bool:

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

    else {
        //it equals no
        }

      

+2


source


why don't you try something like this? I haven't seen your complete project, but it should work like a charm.

- (void)viewDidLoad {
    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(applicationWillResignActive:) name:UIApplicationWillResignActiveNotification object:nil];
    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(applicationWillEnterForeground:) name:UIApplicationWillEnterForegroundNotification object:nil];
}

      

then ...



- (void)applicationWillResignActive:(UIApplication *)application
{
    [[NSUserDefaults standardUserDefaults] setValue:[NSDate date] forKey:@"sleepTime"];
    [[NSUserDefaults standardUserDefaults] synchronize];
}

      

and...

- (void)applicationWillEnterForeground:(UIApplication *)application
{
    NSInteger _timeoutInSeconds = 300;

    NSDate *_sleepTime = [[NSUserDefaults standardUserDefaults] valueForKey:@"sleepTime"];
    if (_sleepTime) {
        NSCalendar *_calendar = [[NSCalendar alloc] initWithCalendarIdentifier:NSGregorianCalendar];
        NSDateComponents *_dateComponents = [_calendar components:NSSecondCalendarUnit fromDate:_sleepTime toDate:[NSDate date] options:0];
        if (_dateComponents.second > _timeoutInSeconds) {
            // expired session
        } else {
            // valid session
        }
    }
}

      

+2


source







All Articles