【问题标题】:Dismiss a .sheet in SwiftUI after an async process has completed?异步过程完成后在 SwiftUI 中关闭 .sheet?
【发布时间】:2019-12-14 01:38:12
【问题描述】:

在调用异步进程以确认用户的 MFA 代码后,我试图在 SwiftUI 中关闭 .sheet。 (我使用的是AWS Amplify Framework)。

我在主视图上设置了一个绑定变量,并在工作表以@Binding var displayMFAView: Bool 显示的视图中引用它。我有一个跟踪用户状态的身份验证助手:@EnvironmentObject var userAuthHelper: UserAuthHelper

以下代码按预期关闭工作表:

func confirmMFACode(verificationCode: String) {
    // Code to confifm MFA...
    print("User confirmed MFA")
    self.userAuthHelper.isSignedIn = true
    self.displayMFAView = false
}

但是,如果我通过 Amplify 的 confirmSignIn 方法调用身份验证过程,

func confirmVerificationMFA(verificationCode: String) {
    AWSMobileClient.default().confirmSignIn(challengeResponse: verificationCode) { (signInResult, error) in
        if let error = error as? AWSMobileClientError {
            // ... error handling ...
        } else if let signInResult = signInResult {
            switch (signInResult.signInState) {
                case .signedIn:
                    print("User confirmed MFA")
                    self.userAuthHelper.isSignedIn = true
                    self.displayMFAView = false
                default:
                    print("\(signInResult.signInState.rawValue)")
                }
        }
    }
}

工作表不会被解雇。我已经尝试将变量赋值包装在DispatchQueue.main.async {... 中,但这也没有解决问题。

...
DispatchQueue.main.async {
    self.userAuthHelper.isSignedIn = true
    self.displayMFAView = false
}
...

事实上,这会在我的日志中抛出以下内容:

不允许从后台线程发布更改;确保在模型更新时从主线程发布值(通过接收(on:) 等运算符)。

switch (... 包装在DispatchQueue 中每个https://stackoverflow.com/a/58288437/217101 在我的日志中给了我同样的警告。

诚然,我对 SwiftUI 或 AWS Amplify 并没有牢牢掌握。我不明白什么?

【问题讨论】:

标签: swiftui amazon-cognito aws-amplify


【解决方案1】:

据我所知,异步调用对状态变量做了一些意想不到的事情,但对 EnvironmentObject 却没有。因此,我将 displayMFAView 存储在 EnvironmentObject 中,而不是 @Binding var displayMFAView: Bool

@EnvironmentObject var settings: UserSettings
@State var mfaCode: String = ""

然后可以通过更新该对象中的布尔值来显示或隐藏.sheet(...

Button(action: {
    self.signIn() // Async call happens here
    self.settings.displayMFAView.toggle()
}) {
    Text("Sign In")
}.sheet(isPresented: self.$settings.displayMFAView) {
    // Example code to capture text 
    TextField("Enter your MFA code", text: self.$mfaCode)
}

Button(action: {
    self.verifyMFACode(verificationCode: self.mfaCode) // async call
}) {
    Text("Confirm")
}

func verifyMFACode() 中,我可以进行异步调用来验证我的用户,然后切换工作表以在成功时消失:

func verifyMFACode(verificationCode: String) {
    AWSMobileClient.default().confirmSignIn(challengeResponse: verificationCode) {
    ...
    case .signedIn:
        self.settings.displayMFAView.toggle()
    ...

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2023-03-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-03-25
    • 2016-08-13
    • 2020-04-23
    • 2017-08-24
    相关资源
    最近更新 更多