gpt4 book ai didi

xcode - SwiftUI 从 SceneDelegate sceneDidBecomeActive 加载 View

转载 作者:行者123 更新时间:2023-12-05 06:21:20 32 4
gpt4 key购买 nike

我正在尝试了解如何从 Swift 函数代码加载 SwiftUI View 。在这个具体情况,我想在从后台状态返回到覆盖敏感数据。我已经创建了一个生物识别登录并且工作正常 - 纯应用程序的 SwiftUI View 。当我将应用程序置于后台并返回时,FaceID 按预期工作,但底层屏幕是可见的。这是一个广义的还有一个问题 - 如何从任何 Swift 函数加载任何 SwiftUI View 。

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
}

我也尝试过使用这样的托管 Controller ,但它也没有用。相同的问题,身份验证有效,但数据可见。

    //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 中添加全屏显示带有身份验证的新 Controller 以隐藏敏感内容

    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 通知即可关闭顶级 Controller

   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)
}

关于xcode - SwiftUI 从 SceneDelegate sceneDidBecomeActive 加载 View ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59851594/

32 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com