2013-02-15 4 views
3

У меня есть функция тайм-аута, где, если приложение неактивно (в фоновом режиме) в течение определенного периода времени, я тайм-аут приложения и отправлю пользователя на экран входа в систему. Я установил ключ timedOut в значениях по умолчанию пользователя YES в моем делете приложения, а затем ссылаюсь на этот ключ в каждом контроллере представления, где, если это ДА, я перехожу на экран входа в систему. На экране входа в систему у меня есть метка, на которой отображается «Тайм-аут сеанса», если «timedOut» - «ДА». Моя проблема заключается в том, что если я вхожу в систему, а затем выйдите из системы очень быстро, ярлык будет отображаться, хотя я явно установил этот ключ в NO сразу после того, как я покажу ярлык, а затем синхронизирую пользовательские значения по умолчанию. Если я жду второй или второй и выйдите из системы, ярлык будет скрыт, как и должно быть. Я решил «проблему», но хотел бы понять поведение.NSUserDefaults не обновляет значение быстро

Код из представления загрузился в моем контроллере входа в систему. Вы могли бы подумать, что это изменит isTimedOut на NO, но когда я сделаю быстрый выход из системы viewdidload, вызывается снова, но isTimedOut - ДА.

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

Я заменил код выше, используя свойство в моем приложении делегат вместо NSUserDefaults и «странное» поведение ушел.

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 КОД

Для выхода из системы, я UIButtonBarItem вызов SEGUE программно. Свойство doLogout указывает контроллеру входа в систему запустить 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 устанавливается в одном месте в делегате приложения.

-(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; 
} 

} 
+1

Не уверен, что четко понять вашу проблему. Но небольшой вопрос: почему бы не использовать какую-то память вместо userDefaults? Какая польза здесь? если бы я был вами, я бы сохранил «переход на задний план» в NSDate, а затем сравнил его, когда приложение выходит на передний план. – Vinzius

+0

Предоставить полный код. Пока что неясно, что происходит. NSUserDefaults хранит все в памяти и сохраняет в flash каждый раз, когда вы вызываете синхронизацию, поэтому даже с быстрыми релогинами это не должно вызывать таких проблем. –

ответ

2

Используйте это:

Чтобы сохранить Bool:

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

загрузить Bool:

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

    else { 
     //it equals no 
     } 
2

почему бы вам не попробовать что-то вроде этого? Я не видел ваш полный проект, но он должен работать как шарм.

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

тогда ...

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

и ...

- (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 
     } 
    } 
} 
+0

UIApplicationWillEnterForegroundNotification не вызывается, когда приложение запускается впервые. Я использую UIApplicationDidBecomeActiveNotification, который вызывается, когда приложение помещается в фоновый режим или запускается впервые. – Nate

+0

@Nate, конечно, это просто идея, вы можете свободно ее настраивать. – holex

Смежные вопросы