Текущий экран входа в приложение AppDelegate

Мне нужно представить конкретный ViewController (определенный в swift) из моего приложения, и он просто не работает. Вот что я делаю:

У меня есть экран входа в систему, определенный в моей раскадровке в файле Main.storyboard. В этой раскадровке есть UINavigationController, который переходит в экран с идентификатором раскладки "LoginVC".

Когда я запускаю приложение в первый раз, все хорошо. Но когда пользователь создает приложение (нажатие кнопки «домой»), я автоматически отключаю пользователя, что означает, что переменная «loggedin» установлена ​​в false в userDefaults.

Когда пользователь нажимает значок приложения для запуска / приоритета приложения, он возвращается к экрану, на котором он был включен, когда он был зашифрован, что является довольно стандартным поведением для приложения, но НЕ является тем, что я хочу здесь.

Внутри AppDelegate applicationDidBecomeActive, я хочу проверить пользовательские значения по умолчанию и посмотреть, если мы вошли в систему, а если нет, то я хочу показать экран входа в систему «LoginVC».

Мой код показан ниже. Код не выдает никаких ошибок, но он никогда не переходит на экран входа в систему – он просто остается на прежнем экране. Что я делаю не так?

Также обратите внимание, что MyLoginVC определяется в swift, поэтому я импортировал -Swift.h int AppDelegate.

Опять же, все компилируется, похоже, что он должен работать, он думает, что он вышел из системы и пытается показать экран входа в систему, но он просто не работает. Есть идеи?

- (void)applicationDidBecomeActive:(UIApplication *)application { NSLog(@"applicationDidBecomeActive"); BOOL loggedIn=[self.engine is_logged_in]; if (loggedIn) { NSLog(@"self.engine says we are logged in"); } else { NSLog(@"self.engine says we are NOT logged in"); [self showLoginUI]; NSLog(@"Are we at login screen yet?"); } } - (void) showLoginUI { UIStoryboard *storyboard = [UIStoryboard storyboardWithName:@"Main" bundle:nil]; MyLoginVC *loginVC = [storyboard instantiateViewControllerWithIdentifier:@"LoginVC"]; if (loginVC) { NSLog(@"loginVC is something"); } else { NSLog(@"loginVC is nil"); } // // Neither of these works! // //[self.window.rootViewController.navigationController presentViewController:loginVC animated:YES completion:nil]; //[self.window.rootViewController.navigationController pushViewController:loginVC animated:YES]; } 

ОБНОВЛЕНИЕ: Я не могу поверить, что я первый человек, которому когда-либо приходилось показывать VC входа, когда приложение возвращается на передний план и обнаруживает, что пользователь теперь вышел из системы. Может быть, я могу предоставить несколько подробностей. Моя раскадровка – Main.storyboard, а самый левый (начальный) VC – простой старый UINavigationController. Это автоматически rootViewController? Является ли тот же rootViewController, что и self.window.rootViewController в AppDelegate? Существует ли какой-либо способ обнаружить приложение, что приложение просто повторно запустило передний план и теперь должно показать VC входа в систему, поскольку пользователь вышел из системы, когда приложение перешло в фоновый режим. Кто-то, должно быть, решил это раньше.

Сквозь проб и ошибок, терпение и множество поисков я наткнулся на правильный ответ или, по крайней мере, на то, как это работает. Вот:

У моей раскадровки есть UINavigationController наверху, которая затем подключается к LoginVC (я не очень люблю парня с раскадрой, и я не писал код интерфейса, поэтому я подозреваю, что «connects» – неправильное слово, но вы получаете идея). У UINavigationController есть инспектор IF @ "LoginScreen", а в Login VC есть идентификатор @ "LoginVC". Класс LoginVC уже правильно обрабатывает случай запуска приложения и правильно проверяет, не был ли пользователь уже вошел в систему, перейдя на главный экран приложения, если пользователь уже зарегистрировался. Случай, который мне нужно было обработать, заключался в том, что пользователь минимизирует app (нажав кнопку home) и где я перегрузил AppDelegate applicationDidEnterBackground, чтобы вывести пользователя из системы.

Когда пользователь возобновит приложение (нажав на значок), приложение перейдет на передний план и снова станет активным. В applicationDidBecomeActive я проверяю userDefaults, чтобы узнать, все еще зарегистрирован пользователь. Если пользователь все еще зарегистрирован, я ничего не делаю. Если пользователь НЕ вошел в систему, я вызываю свою собственную функцию AppDelegate showLoginUI, чтобы сообщить приложению переключиться на интерфейс входа в систему. Вот эта функция:

 -(void) showLoginUI { self.window.rootViewController = [self.window.rootViewController.storyboard instantiateViewControllerWithIdentifier:@"LoginScreen"]; } 

Эта одна строка кода внутри этой функции – единственное, что мне нужно было сделать, и она работала как шарм. Похоже, он устанавливает окно rootViewController в новый экземпляр UINavigationController, который является корневым VC в раскадровке. Не уверен, что волшебство происходит под капотом, но это сработало для меня.

Для меня нажатие этого viewController на вершину стека кажется неправильным. Я бы попытался вытащить другие viewControllers из стека, пока не вернусь в loginVC. UINavigationController обеспечивает очень удобный способ для этого:

 [self.window.rootViewController.navigationController popToViewController:savedLoginVC animated:NO]; 

https://developer.apple.com/library/ios/documentation/UIKit/Reference/UINavigationController_Class/#//apple_ref/occ/instm/UINavigationController/popToViewController:animated :

Когда ваше приложение вернется с фона на передний план. Затем любое действие, которое вы хотите выполнить, записывает этот код в

AppDelegate -> applicationWillEnterForeground метод

 - (void)applicationWillEnterForeground:(UIApplication *)application { // Called as part of the transition from the background to the active state; here you can undo many of the changes made on entering the background. }