TouchID аутентифицирован, но диалоговое окно все еще отображается

Я использую TouchID, чтобы помочь пользователям войти в мое приложение. Всякий раз, когда приложение запускается, первое, что видит пользователь, — это диалоговое окно TouchID.

Моя проблема в том, что если пользователь запускает мое приложение, когда его палец уже находится на кнопке «Домой», пользователь сразу же аутентифицируется, и только тогда отображается диалоговое окно TouchID. Затем — независимо от того, что я делаю, чтобы закрыть диалоговое окно (ввести пароль или отменить), серый экран всегда отображается над моим приложением, и мне приходится перезагружать iPhone, чтобы продолжить работу.

Как я могу это решить?


person YogevSitton    schedule 20.11.2014    source источник
comment
Я думаю, что это ошибка ОС, потому что я видел это в паре приложений. Вы мало что можете сделать, кроме как заполнить радар.   -  person EmilioPelaez    schedule 20.11.2014
comment
Я видел, как это было решено по крайней мере в одном приложении. Я тоже хочу решить эту проблему :)   -  person YogevSitton    schedule 20.11.2014
comment
Я решил это в своем приложении, переместив код TouchId из viewDidLoad в viewDidAppear. Я думаю, что время может быть важным.   -  person Daniel    schedule 25.11.2014


Ответы (2)


Убедитесь, что диалоговое окно Touch ID отображается только тогда, когда состояние приложения активно. Если вы отобразите его сразу во время процесса запуска (это означает, что Приложение все еще технически находится в неактивном состоянии), могут возникнуть проблемы такого рода. Это не задокументировано, и я обнаружил это на собственном горьком опыте.

Например, чтобы убедиться, что оно запускается, когда приложение активно, вы можете проверить текущее состояние приложения и либо запустить его немедленно, либо при получении уведомления applicationDidBecomeActive. См. пример ниже:

- (void)setup
{
    [[NSNotificationCenter defaultCenter] addObserver:self
                                             selector:@selector(applicationDidBecomeActive:)
                                                 name:UIApplicationDidBecomeActiveNotification
                                               object:nil];
}

- (void)dealloc
{
    [[NSNotificationCenter defaultCenter] removeObserver:self];
}

- (void)viewWillAppear:(BOOL)animated
{
    [super viewWillAppear:animated];

    // We need to be in an active state for Touch ID to play nice
    // If we're not, defer the presentation until we are
    if([UIApplication sharedApplication].applicationState == UIApplicationStateActive)
    {
        [self presentTouchID];
    }
    else
    {
        __weak __typeof(self) wSelf = self;
        _onActiveBlock = ^{
            [wSelf presentTouchID];
        };
    }
}

-(void)applicationDidBecomeActive:(NSNotification *)notif
{
    if(_onActiveBlock)
    {
        _onActiveBlock();
        _onActiveBlock = nil;
    }
}

- (void)presentTouchID
{
    _context = [[LAContext alloc] init];
    _context.localizedFallbackTitle = _fallbackTitle;
    [_context evaluatePolicy:LAPolicyDeviceOwnerAuthenticationWithBiometrics
             localizedReason:_reason
                       reply: ^(BOOL success, NSError *authenticationError)
     {
         // Handle response here
     }];
}
person WDUK    schedule 20.11.2014

Эта проблема возникает, когда вы используете Touch ID сразу после запуска приложения и меняете текущий контроллер представления или окно в блоке ответа для оценкиPolicy:localizedReason:reply:.

Просто подождите некоторое время после проверки доступности (canEvaluatePolicy:error:) Touch ID.

Поместите AssessmentPolicy:localizedReason:reply: внутри dispatch_after() следующим образом:

dispatch_after(dispatch_time(DISPATCH_TIME_NOW, .5f * NSEC_PER_SEC), dispatch_get_main_queue(), ^{
    [context evaluatePolicy:LAPolicyDeviceOwnerAuthenticationWithBiometrics
                    localizedReason:NSLocalizedString(@"Use Touch ID to Unlock", nil)
                              reply:^(BOOL success, NSError *error) {
                                  if (success) {
                                  }else {
                                      if (error.code == kLAErrorUserCancel) {

                                      }
                                  }
                              }];
});

Я сделал пример проекта, а также решение здесь:

https://github.com/RungeZhai/TouchIDIssue

Ответ Aviram (godmoney) тоже работает.

person Ge Liu    schedule 24.11.2014
comment
По моему опыту, если вам нужно добавить задержку в свой код, ваше решение решает не ту проблему. (кроме анимации, конечно!) Решение WDUK лучше. - person Paul Cezanne; 30.06.2016