iOS отменяет диалоговое окно аутентификации TouchID программно

Можно ли программно отменить диалоговое окно оповещения TouchID после вызова LAContext.evaluatePolicy? Если да: как?


person Sven-Michael Stübe    schedule 14.12.2015    source источник
comment
Вопрос не ясен, чего вы пытаетесь достичь?   -  person Vijay    schedule 15.12.2015
comment
LAContext.evaluatePolicy открывает диалоговое окно с запросом TouchID. Я хочу закрыть диалог из своего кода. например через несколько секунд, если пользователь ничего не сделал.   -  person Sven-Michael Stübe    schedule 15.12.2015
comment
Интересно, что они добавили код ошибки AppCancel, но я не вижу никакого API для его отмены в документации. В различиях iOS 9.0 есть метод LAContext invalidate, но не уверен, что его будет достаточно, чтобы считаться общедоступным.   -  person jcaron    schedule 15.12.2015
comment
Спасибо. Я посмотрю.   -  person Sven-Michael Stübe    schedule 15.12.2015


Ответы (2)


Не каждый API, публикуемый Apple, попадает в документацию на сайте developer.apple.com (или в средстве просмотра документов Xcode). В списках различий API перечислены общедоступные API, поэтому все, что вы там видите, находится в файлах заголовков (см. LocalAuthentication/LAContext.h) и в интерфейсах Swift, созданных из этих заголовков. И все, что находится в заголовках, является общедоступным API, поэтому вы можете вызывать его.

Иногда (но не всегда) недокументированные API имеют достойные комментарии в заголовке, объясняющие, как их использовать... к счастью, LAContext.invalidate() является одним из них:

/// Invalidates the context.
///
/// @discussion The context is invalidated automatically when it is (auto)released. This method
///             allows invalidating it manually while it is still in scope.
///
///             Invalidation terminates any existing policy evaluation and the respective call will
///             fail with LAErrorAppCancel. After the context has been invalidated, it can not be
///             used for policy evaluation and an attempt to do so will fail with LAErrorInvalidContext.
///
///             Invalidating a context that has been already invalidated has no effect.
@available(iOS 9.0, *)
public func invalidate()

Действительно, похоже, что вызов invalidate() во время отображения предупреждения Touch ID должен отклонить его. (Сам не пробовал.)


Обновление iOS 11: обратите внимание, что на устройствах с Face ID вместо Touch ID пользовательский интерфейс, похожий на предупреждение/HUD, который появляется, когда вы звоните LAContext.evaluatePolicy, не требует и не разрешает взаимодействие и закрывается после успешной аутентификации. . Теоретически вызов invalidate по-прежнему отклоняет его (или последующее интерактивное оповещение, которое появляется, если Face ID не идентифицирует пользователя).

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

person rickster    schedule 15.12.2015
comment
Работает как положено. :) - person Sven-Michael Stübe; 15.12.2015
comment
Я не могу отклонить с помощью invalidate(). Что я делаю не так? :) - person hfossli; 04.10.2017

В моем случае я выясняю, почему он не работает, потому что экземпляр LAContext, который я пытаюсь аннулировать(), не является тем же экземпляром, который я вызываю AssessmentPolicy().

Поэтому вам нужно убедиться, что все ViewControllers совместно используют один и тот же экземпляр. Свифт 4

public class MyBiometryUtility: NSObject {
static private var sharedBiometry: MyBiometryUtility? = nil
var context: LAContext = LAContext()
@objc public static func sharedInstance() -> MyBiometryUtility{
        if let sharedBiometry = sharedBiometry {
            return sharedBiometry;
        } else{
            sharedBiometry = MyBiometryUtility()
            return sharedBiometry!
        }
    }
public func tryBiometryAuth() { ... }
public func closeBiometryAuth() {... }

В SomeViewController.swift

func buttonTapped(sender: Any){
    // show dialog.
    MyBiometryUtility.sharedInstance().tryBiometryAuth()
}
func timerCountDown(){
    // close dialog.
    if tooLong() {
        MyBiometryUtility.sharedInstance().closeBiometryAuth()
    }
}
person John    schedule 08.09.2020