【发布时间】:2020-05-24 13:44:27
【问题描述】:
我正在试验 SwiftUI,但很难为我的应用找出合适的架构。
我想要实现的目标很简单。我想要一个初始屏幕,根据当前的身份验证状态显示给定用户的注册屏幕或主屏幕。一旦进行了身份验证,我无法弄清楚如何使初始屏幕从注册屏幕中获取更改。以下是一些相关代码:
struct InitialView: View {
@EnvironmentObject var viewModel: InitialViewModel
var body: some View {
VStack {
if viewModel.auth.identity != nil {
NewHomeView()
} else {
SignInView()
}
}
}
}
在登录视图中,我有一个常用的登录表单,当用户按下登录按钮时,我想向后端发送登录请求并记住生成的令牌。
class SignInViewModel: ObservableObject {
private let auth: AuthStore
private let signInApi: SignInApi
private var cancellableSet: Set<AnyCancellable>
// Input
@Published var name: String = ""
@Published var password: String = ""
@Published var showSignUp: Bool = false
// Output
@Published var authSuccess: Bool = false
init(auth: AuthStore, signInApi: SignInApi) {
self.auth = auth
self.signInApi = signInApi
self.cancellableSet = Set<AnyCancellable>()
}
func signIn() {
signInApi.signIn(email: name, password: password).sink(receiveCompletion: { _ in }) { response in
self.auth.identity = Identity(
person: Person(id: 1, name: "user", sex: nil, birthday: nil),
token: response.token
)
self.authSuccess = true
}.store(in: &cancellableSet)
}
}
但是,这不起作用。即使在单击登录按钮后,初始视图也不会更新。请注意,我将相同的 AuthStore 传递给两个视图模型。
let auth = AuthStore()
// Create the SwiftUI view that provides the window contents.
let contentView = InitialView()
.environmentObject(InitialViewModel(auth: auth))
.environmentObject(SignInViewModel(auth: auth, signInApi: SignInApi()))
其中 AuthStore 被定义为
class AuthStore: ObservableObject {
@Published var identity: Identity? = nil
}
理想情况下,我希望能够 1) 让每个视图与自己的 VM 配对 2) 让每个 VM 通过 @EnvironmentObject 访问全局状态。但是,@EnvironmentObject 似乎仅限于视图?如果是这样,我如何从需要它的每个 VM 中访问全局身份验证状态?
【问题讨论】:
-
你尝试过这个教程的一个小项目吗? hackingwithswift.com/quick-start/swiftui/…顺便有两个观点……正是你想学的
-
嘿,我在询问之前查看了那个链接。我没有使用它,因为它基本上迫使我停止使用 MVVM 并在视图内进行所有状态管理。在您发布的链接的语言中,我希望有两个视图模型可以访问相同的 UserSettings(理想情况下从 SceneDelegate 中注入一次)。这可能吗?
-
查看答案下方的讨论,您必须检查@Published 包装器的用途,以及它是如何工作的stackoverflow.com/questions/60119057/…
-
另一个问题,哪个环境对象可以在你的 contentView 中访问???
-
我在这里回答了类似的问题:stackoverflow.com/questions/60134061/…
标签: ios swift mvvm swiftui combine