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