Я экспериментирую со 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) иметь каждый view должен быть в паре со своей собственной виртуальной машиной 2) иметь доступ к глобальному состоянию каждой виртуальной машины через @EnvironmentObject. Однако, кажется, что @EnvironmentObject ограничен только представлениями? Если да, то как мне получить доступ к глобальному состоянию аутентификации внутри каждой виртуальной машины, для которой это требуется?