Xcode 来自ScenedLegate ScenedDBeComeActive的SwiftUI加载视图

Xcode 来自ScenedLegate ScenedDBeComeActive的SwiftUI加载视图,xcode,swiftui,Xcode,Swiftui,我试图理解如何从Swift函数代码加载SwiftUI视图。在这个 具体来说,我想在从后台状态返回时加载一个视图 覆盖敏感数据。我已经创建了一个生物识别登录,它可以很好地工作-纯 应用程序的快捷界面视图。当我将应用程序放到后台并返回时 FaceID按预期工作,但底层屏幕可见。这是一个广义的概念 还有一个问题-如何从任何Swift函数加载任何SwiftUI视图 func sceneDidBecomeActive(_ scene: UIScene) { if userDefaultsMana

我试图理解如何从Swift函数代码加载SwiftUI视图。在这个 具体来说,我想在从后台状态返回时加载一个视图 覆盖敏感数据。我已经创建了一个生物识别登录,它可以很好地工作-纯 应用程序的快捷界面视图。当我将应用程序放到后台并返回时 FaceID按预期工作,但底层屏幕可见。这是一个广义的概念 还有一个问题-如何从任何Swift函数加载任何SwiftUI视图

func sceneDidBecomeActive(_ scene: UIScene) {

    if userDefaultsManager.wentToBackground {
        if userDefaultsManager.enableBiometrics {
            BiometricsLogin(userDefaultsManager: userDefaultsManager).authenticate()
            //what I want is something like:
            //BiometricsLogin(userDefaultsManager: userDefaultsManager)
            //kinda like you would do in a TabView
            //that would run the authentication just like starting the app
            userDefaultsManager.wentToBackground = false
        }
    }
}
登录代码非常通用:

struct BiometricsLogin: View {
    @ObservedObject var userDefaultsManager: UserDefaultsManager

    var body: some View {
        NavigationView {
            VStack {
                Image("CoifMeCrop180")
                .onAppear {
                    self.authenticate()
                }
            }//vstack
        }//nav
    }

    func authenticate() {
        let context = LAContext()
        var error: NSError?

        if context.canEvaluatePolicy(.deviceOwnerAuthenticationWithBiometrics, error: &error) {
            let reason = "The app uses Biometrics to unlock you data"
            context.evaluatePolicy(.deviceOwnerAuthentication, localizedReason: reason) { (success, authenticationError)
                in
                DispatchQueue.main.async {
                    if success {
                        self.userDefaultsManager.isAuthenticated = true
                        self.userDefaultsManager.selectedTab = 1
                    } else {
                        if self.userDefaultsManager.enableBiometrics {
                            self.userDefaultsManager.isAuthenticated = false
                            self.userDefaultsManager.selectedTab = 3
                        } else {
                            self.userDefaultsManager.isAuthenticated = false
                            self.userDefaultsManager.selectedTab = 1
                        }
                    }
                }
            }
        } else {
            //no biometrics - deal with this elsewhere
            //consider an alert here
        }
    }//authenticate
}
我也尝试过使用这样的主机控制器,但也不起作用。同样的 问题,身份验证工作正常,但数据可见

    //this does not work
    let controller = UIHostingController(rootView: BiometricsLogin(userDefaultsManager: userDefaultsManager))
    self.window!.addSubview(controller.view)
    self.window?.makeKeyAndVisible()

任何指导都将不胜感激。Xcode 11.3.1(11C504)

这里是可能的方法

sceneDidBecomeActive
中,添加全屏显示具有身份验证的新控制器,以隐藏敏感内容

    func sceneDidBecomeActive(_ scene: UIScene) {
        let controller = UIHostingController(rootView: BiometricsLogin(userDefaultsManager: userDefaultsManager))
        controller.modalPresentationStyle = .fullScreen

        self.window?.rootViewController?.present(controller, animated: false)
    }
现在它需要在身份验证完成时关闭它,因此为此添加通知

extension SceneDelegate {
    static let didAuthenticate = Notification.Name(rawValue: "didAuthenticate")
}
。。。在
SceneDelegate

class SceneDelegate: UIResponder, UIWindowSceneDelegate {

    var window: UIWindow?

    private var authenticateObserver: AnyCancellable?

    func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) {

        let contentView = ContentView()

        if let windowScene = scene as? UIWindowScene {
            self.authenticateObserver = NotificationCenter.default.publisher(for: SceneDelegate.didAuthenticate)
                .sink { _ in
                    self.window?.rootViewController?.dismiss(animated: true)
                }

            let window = UIWindow(windowScene: windowScene)
            ...
验证完成后,只需发布
didAuthenticate
通知即可解雇顶级控制器

   DispatchQueue.main.async {
        if success {
            self.userDefaultsManager.isAuthenticated = true
            self.userDefaultsManager.selectedTab = 1
        } else {
            if self.userDefaultsManager.enableBiometrics {
                self.userDefaultsManager.isAuthenticated = false
                self.userDefaultsManager.selectedTab = 3
            } else {
                self.userDefaultsManager.isAuthenticated = false
                self.userDefaultsManager.selectedTab = 1
            }
        }
        NotificationCenter.default.post(name: SceneDelegate.didAuthenticate, object: nil)
    }

我知道你要去哪里。我需要稍微玩玩一下——第一次尝试让我有了几乎相同的行为,只是新视图在数据之后不久出现,然后在身份验证完成后被驳回。也许我留下了一些原始代码。如果成功打开“State”logged:Bool inside.onappear,那么authenticate()func中的“@escaping”呢?