Использование applicationwillenterforeground для экрана кода доступа

До iOS4 начальный контроллер представления моего приложения проверял переменную настроек включения/выключения пароля в viewWillAppear и, если он был установлен, отображал модальный экран кода доступа, который оставался там до тех пор, пока не был введен правильный код доступа или не была нажата кнопка «Домой».

С iOS4, если мое приложение было в фоновом режиме, я хотел бы, чтобы пользователь чувствовал себя комфортно, что данные, содержащиеся в приложении, не легко доступны, если бы они передали свой телефон кому-то для использования.

Поскольку приложение может вернуться на любой экран (экран, на котором приложение было последним), я решил, что буду использовать UIApplicationWillEnterForegroundNotification повсюду с локальными селекторами (дублирующими методами enterPasscode), каждый из которых имеет правильный контроллер представления для нажатия на основе локальный экран, но должен быть лучший способ.

У меня может быть небольшое концептуальное недопонимание здесь. Может кто-нибудь предложить другой подход или подтолкнуть меня к следующему шагу. Могу ли я использовать это как общий метод, но при этом знать правильный контроллер локального представления для нажатия?

Спасибо

РЕДАКТИРОВАТЬ/ОБНОВИТЬ:

Краткая версия: это работает, но может ли быть лучший способ (любая помощь приветствуется)...

Я создал стандартный синглтон с контроллером представления.

PasscodeView.h, содержащий:

UIViewController *viewController;
@property (nonatomic, retain) UIViewController *viewController;

PasscodeView.m, содержащий:

@synthesize viewController;

Я поместил это в AppDelegate:

-(void)applicationWillEnterForeground:(UIApplication*)application {

    PasscodeView *passcodeView = [PasscodeView sharedDataManager];
    UIViewController *currentController =  [passcodeView viewController];
    NSLog(@"%@", currentController);  //testing
    EnterPasscode *passcodeInput = [[EnterPasscode alloc] initWithNibName:@"Passcode" bundle:nil];
    [currentController presentModalViewController:passcodeInput animated:NO];
    [passcodeInput release];
}

и следующее во всех моих viewDidLoad, обновляя текущий контроллер представления при переходе на каждый экран (всего 2 строки, но все же кажется, что есть лучший способ):

PasscodeView *passcodeView = [PasscodeView sharedSingleton];
passcodeView.viewController = [[self navigationController] visibleViewController];

Хотелось бы, чтобы был способ получить текущий контроллер представления из applicationWillEnterForeground, но я не смог его найти - любая помощь здесь по-прежнему приветствуется.

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

UINavigationController *passcodeNavigationController = [[UINavigationController alloc] initWithRootViewController:passcodeInput];
[currentController presentModalViewController: passcodeNavigationController animated:NO];

person Community    schedule 08.08.2010    source источник


Ответы (2)


Вы можете централизовать это поведение в своем делегате приложения, реализовав

-(void)applicationWillEnterForeground:(UIApplication*)application;

Вы можете реализовать синглтон, который хранит текущий соответствующий контроллер модального представления, обновляя его в viewWillAppear в каждом из ваших контроллеров представления.

Редактировать: я предполагал, что у вас уже есть ряд контроллеров представления, которые вы хотели показать. Сомневаюсь, что вам это действительно нужно. Если у вас есть один из них, скажем, PasscodeInputController, то ваше приложениеWillEnterForeground будет выглядеть примерно так:

-(void)applicationWillEnterForeground:(UIApplication*)application {
    UIViewController *currentController =  [window rootViewController];
    PasscodeInputController *passcodeInput = [[PasscodeInputController alloc] init];

    [currentController presentModalViewController:passcodeInput animated:NO];
    [passcodeInput release];
}

Я надеюсь, что это касается вашего вопроса более прямо.

person Seamus Campbell    schedule 08.08.2010
comment
Вот с чего я начал, но не знал, что поставить для контроллера представления - я подумаю об этом, а затем попробую. - person Matt Winters; 08.08.2010
comment
Я концептуально понимаю, что вы пытаетесь - представить экран кода доступа здесь, а не на каждом контроллере представления - похоже, что он должен работать, но это не так. Скопировал код точно как есть (изменил PasscodeInputController на EnterPasscode), строится нормально, без ошибок, без предупреждений, но ничего не появляется. Сначала я не был знаком со свойством rootViewController в UIWindow, но после прочтения, что это такое, похоже, что оно должно работать, хотя других примеров я не нашел. Я попробовал еще пару вещей - попытался использовать там навигационный контроллер, попробовал подвид, makeKeyAndVisible, но ничего. - person Matt Winters; 09.08.2010
comment
Однако вы получаете ненулевое значение? - person Seamus Campbell; 09.08.2010
comment
Ваше приложение основано на навигационном контроллере? Сохраняете ли вы навигационный контроллер как свойство в своем делегате приложения? Попробуйте получить текущее представление (в [yourAppDelegate applicationWillEnterForeground]) с помощью currentController = [[self navController] visibleViewController], а затем вызовите для него presentModalViewController. - person Seamus Campbell; 09.08.2010
comment
@Seamus См. РЕДАКТИРОВАТЬ/ОБНОВИТЬ выше. Спасибо, что направили меня в правильном направлении. Ваши вопросы: Нет, currentController был нулевым до того, что я сделал в качестве своего «решения». Вероятно, следовало бы предоставить более подробную информацию о структуре приложения. Приложение имеет контроллер панели вкладок, каждая из 5 вкладок имеет свой собственный навигационный контроллер, множество pushViewControllers и PresentModelViewControllers и много разных мест для входа в фон. Не сохранил навигационный контроллер как свойство делегата приложения. Я попробовал вариант, но не помогло. Дополнительная помощь приветствуется, чтобы заставить ваш подход работать. - person Matt Winters; 10.08.2010

Поведение вашего приложения при повторном выходе на передний план должно быть максимально похоже на то, когда оно запускается в первый раз. Имея это в виду, вы можете объединить applicationDidFinishLaunching: с applicationWillEnterForeground:, но, учитывая, что некоторые виды уже могут быть загружены. Код примерно такой:

id myState = (isReentering) ? [self validateState] : [self loadStateFromSave];
NSArray * keyForObjectToLoad = [self objectsToLoadForState:myState];
for(NSString * key in keyForObjectToLoad)
    if(![self objectForKey:key]) [self loadObjectForKey:key];

В зависимости от детализации вашего приложения может потребоваться первоначальная работа, но у него есть некоторые преимущества:

  • Это гарантирует, что запуск и повторный запуск будут одинаковыми, поэтому пользовательский опыт не будет «случайным».
  • Вы можете легче освободить много ненужной памяти, когда работаете в фоновом режиме.
  • Централизованно управлять состоянием вашего приложения проще.
person mohsenr    schedule 08.08.2010