从哪里调用 Touch ID 逻辑?

From where to call Touch ID logic?

我是 iOS 的新手。我正在应用程序中尝试本地身份验证框架。我的应用程序流程就像当用户打开应用程序时,他可以看到启动画面,然后如果他是新用户,他将重定向到登录屏幕,然后转到仪表板屏幕。从登录开始,如果他点击记住我,下次当用户打开应用程序时,他将直接重定向到仪表板。

我只是不明白我在哪个屏幕上添加了 authenticationWithTouchID 逻辑。在应用程序打开时,我想显示 TouchID 弹出窗口,以便用户可以进行身份​​验证并重定向到仪表板。

更新:1

我正在检查 AppDelegatedidFinishLaunchingWithOptions() 中的 remember me 是否真实,因此,我曾经打开过特定的 UIViewController。因此,在相同的方法中,我只检查用户是否启用了触摸 ID,如果用户对触摸 ID 进行了身份验证,那么我将显示弹出窗口,否则将正常重定向到仪表板。这是一个正确的方法吗?我想问的另一件事是暂停应用程序时单击主页按钮,如果我想在应用程序重新打开时再次显示触摸 ID 是调用该身份验证方法。它会去 applicationWillEnterForeground() 吗?

更新:2

当使用 applicationWillEnterForeground()

打开 Touch ID 时,仪表板内容在后台可见

如果您的用户已经登录,请保存在您的 UserDefaults 中,然后按如下方式继续应用程序启动:

func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
    // Override point for customization after application launch.

    self.window = UIWindow(frame: UIScreen.main.bounds)
    if !isLoggedIn {
        let loginController = LoginController()
        self.window?.rootViewController = loginController
        self.window?.makeKeyAndVisible()
        return true
    }
    let authController = AuthenticaeController()
    self.window?.rootViewController = authController
    self.window?.makeKeyAndVisible()

    return true
}

其中 isLoggedIn bool 应该是您从 UserDefaults 中存储的值。

您必须将 true 存储在用户成功登录的 userDefault

例如 UserDefaults.standard.setValue("true", forKey: "isLogin")

AppDelegate.Swift

 func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {

        let islogin = UserDefaults.standard.bool(forKey: "isLogin")

        if islogin
        {
           self.NextViewController(storybordid: "DashBoardViewIdentifier")
        }
        else
        {
            self.NextViewController(storybordid: "LoginViewIdentifier")
        }
        return true
    }

并在 AppDelegate.swift

中创建一个 method
   func NextViewController(storybordid:String)
    {

        let storyBoard:UIStoryboard = UIStoryboard(name: "Main", bundle: nil)
        let exampleVC = storyBoard.instantiateViewController(withIdentifier:storybordid )
        let nav = UINavigationController(rootViewController: exampleVC)
        nav.navigationController?.setNavigationBarHidden(true, animated: false)
        self.window = UIWindow(frame: UIScreen.main.bounds)
        self.window?.rootViewController = nav
        self.window?.makeKeyAndVisible()
    }

Based on my experience, You need to separate both authentication related and other UIViewController code. I suggest create a block-based singleton class for Bio-matric authentication (TouchID and FaceID)

参考 awsome 基于块的身份验证库 BiometricAuthentication 供您参考。

我建议将所有与身份验证相关的代码保留在 Login 屏幕中。

自动登录请参考以下代码。

override func viewWillAppear(_ animated: Bool) {
    super.viewWillAppear(animated)
    if isRemmberMe{
        BioMetricAuthenticator.authenticateWithBioMetrics(reason: "") { (result) in

            switch result {
            case .success( _):
                print("Redirect into dashboard screen")
            case .failure(let error):
                print("Authentication Failed")
            }
        }
    }
}

If you go with this approach then no need to write extra code in AppDelegate.swift file because of your rootViewController always the Login screen. Just set your initial controller Login screen from storyboard

更新:1

问题:这种方法正确吗?

Yes, It is a proper way to do this, But code centralization for Bio-matric authentication keep in mind.

问题:如果应用程序状态发生变化,我如何管理 TouchID 或 FaceID 管理

You can go with applicationWillEnterForeground OR applicationDidBecomeActive if application state was changed. One more thing, I would like to mention above both methods are also called when the user open app freshly. If you want completely restrict the user to access the app content then go with applicationWillEnterForeground() otherwise you can go with applicationDidBecomeActive

更新:2

如果您想限制应用内容,您需要手动添加虚拟模糊 UIView

代码:

let blurEffect = UIBlurEffect(style: .Light)
let blurVisualEffectView = UIVisualEffectView(effect: blurEffect)
blurVisualEffectView.frame = view.bounds
self.view.addSubview(blurVisualEffectView)

认证成功则移除

blurVisualEffectView.removeFromSuperview()