gpt4 book ai didi

ios - SwiftUI从ViewModel访问全局状态

转载 作者:行者123 更新时间:2023-12-03 10:41:43 27 4
gpt4 key购买 nike

我正在尝试SwiftUI,并且很难找出适合我的应用的架构。

我想要实现的目标很简单。我想要一个初始屏幕,该屏幕根据当前身份验证状态显示给定用户的注册屏幕或主屏幕。身份验证完成后,我无法确定如何从注册屏幕进行初始屏幕拾取更改。这是一些相关的代码:

struct InitialView: View {
@EnvironmentObject var viewModel: InitialViewModel

var body: some View {
VStack {
if viewModel.auth.identity != nil {
NewHomeView()
} else {
SignInView()
}
}
}
}

在登录 View 中,我有一个通常的登录表单,当用户按下登录按钮时,我想向后端发送登录请求并记住生成的 token 。


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)
}
}

但是,这不起作用。即使单击登录按钮后,初始 View 也不会更新。请注意,我将相同的AuthStore传递给两个 View 模型。

  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)将每个 View 与其自己的VM配对2)通过@EnvironmentObject使每个VM访问全局状态。但是,似乎@EnvironmentObject只限于 View ?如果是这样,我如何从每个需要它的VM中访问全局身份验证状态?

最佳答案

至于提供的代码,我将其更改如下

struct InitialView: View {
@EnvironmentObject var viewModel: InitialViewModel
@EnvironmentObject var signIn: SignInViewModel

var body: some View {
VStack {
if signIn.authSuccess {
NewHomeView()
} else {
SignInView()
}
}
}
}

以及将发布者重定向到主线程
    signInApi.signIn(email: name, password: password)
.receive(on: RunLoop.main) // << following update should be on main thread
.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)

关于ios - SwiftUI从ViewModel访问全局状态,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60130090/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com