アプリが一定期間アイドル状態 (バックグラウンド) の場合にタイムアウト機能があり、アプリをタイムアウトしてユーザーをログイン画面に送ります。アプリケーション デリゲートでユーザー デフォルトの「timedOut」キーを YES に設定し、各ビュー コントローラでそのキーを参照します。YES の場合は、ログイン画面に移動します。ログイン画面に、「timedOut」が「YES」の場合、「セッションがタイムアウトしました」と表示されるラベルがあります。私の問題は、ログインしてすぐにログアウトすると、ラベルを表示した直後にそのキーを明示的に NO に設定し、ユーザーのデフォルトを同期しても、ラベルが表示されることです。1 ~ 2 秒待ってからログアウトすると、本来あるべき姿でラベルが非表示になります。 「問題」は解決しましたが、動作を理解したいと思います。
ビューからのコードがログイン ビュー コントローラーに読み込まれました。これにより isTimedOut が NO に変更されると思われるかもしれませんが、クイック ログアウトを行うと、viewdidload が再度呼び出されますが、isTimedOut は 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];
}
アップデート
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;
}
その他のコード
ログアウトするには、プログラムでセグエを呼び出す UIButtonBarItem があります。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 は、アプリ デリゲートの 1 つの場所で設定されます。
-(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;
}
}