【问题标题】:Communicating between AppDelegate and SwiftUI ViewAppDelegate 和 SwiftUI 视图之间的通信
【发布时间】:2020-08-10 06:33:23
【问题描述】:

我正在尝试使用 AWS Amplify 框架实现自定义登录 UI。我已经成功实现了signIn()函数,如下:

public func signIn(username: String, password: String) {
        _ = Amplify.Auth.signIn(username: username, password: password) { result in
            switch result {
            case .success(_):
                print("Sign in succeeded")
                // nothing else required, the event HUB will trigger the UI refresh
            case .failure(let error):
                print("Sign in failed \(error)")
                
                // in real life present a message to the user
            }
        }
    }

以上代码已放在我的 AppDelegate 文件中。现在我想做的是在登录失败时在我的登录视图中向用户显示一条消息,但我不知道如何将错误从 signIn() 函数传递到登录视图。这是我的登录视图类的相关部分:

  let app = UIApplication.shared.delegate as! AppDelegate
                          
                            self.phoneField?.bindUserInputToPhoneNumber()
                            self.deleteWhitespaceAndParensFromUserInput()
                            
                            app.signIn(username: self.phoneNumber, password: self.password)

任何帮助将不胜感激。

【问题讨论】:

  • 它看起来不像 SwiftUI 代码(没有视图类),你不是把主题和 UIKit 混淆了吗?

标签: ios swiftui aws-amplify


【解决方案1】:

最简单的方法是创建某种模型对象来为您保存这些数据。您可以从 ObservableObject 开始,您将传递给您的根 ContentView(如果您继续从模板中使用它):

final class Model: ObservableObject {

  struct AuthStatus {
    case unknown
    case loggedIn(User) // or whatever your auth object/struct etc. is
    case error(Error)
  }

  @Published var authStatus: AuthStatus = .unknown
}

现在您可以通过几种不同的方式将其传递给您的ContentView,但对于这种全局状态来说,最好的方法之一是EnvironmentObject。由于您提到了AppDelegate,我假设您没有使用新的 SwiftUI only 应用程序生命周期代码,这意味着您正在使用UIHostingController。在AppDelegate 中添加以下内容。

var window: UIWindow?
var model: Model = .init()

然后这应该进入您设置根视图控制器的applicationDidFinishLaunching

window?.rootViewController = UIHostingController(root:
   ContentView()
     .environmentObject(model)
)

现在你的内容视图可以声明它想要这个环境对象:

struct ContentView: View {
  @EnvironmentObject private var model: Model // swiftui will resolve this for you

  var body: some View {
    Text("Auth status: \(model.authStatus)")
  }
}

如果您想更轻松地区分错误等,您可能需要在模型中创建一个额外的 @Published var,而不是像我在这里所做的那样将其组合成一个 enum

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2020-01-09
    • 1970-01-01
    • 1970-01-01
    • 2011-11-21
    • 2016-06-06
    • 1970-01-01
    • 2011-09-10
    • 2011-09-06
    相关资源
    最近更新 更多