在AppDelegate和SwiftUI视图之间进行通信

时间:2020-08-10 06:33:23

标签: ios swiftui aws-amplify

我正在尝试使用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()函数传递到登录视图。这是我的Login视图类的相关部分:

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

任何帮助将不胜感激。

1 个答案:

答案 0 :(得分: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变量,而不是像我在这里所做的那样合并成一个enum