Marc
10/08/2023, 9:00 AMmohamed rejeb
10/08/2023, 11:00 AMMarc
10/08/2023, 11:04 AMfun onEvent(event: LoginEvent) {
when (event) {
is LoginEvent.ChangePasswordText -> _state.update { it.copy(
passwordText = event.password
) }
is LoginEvent.ChangeUsernameText -> _state.update { it.copy(
usernameText = event.username
) }
is LoginEvent.TogglePasswordVisibility -> _state.update { it.copy(
isPasswordVisible = !it.isPasswordVisible
) }
is LoginEvent.SubmitLogin -> login(_state.value)
is LoginEvent.DismissErrorBox -> _state.update { it.copy(
isError = false
) }
}
}
mohamed rejeb
10/08/2023, 11:06 AMMarc
10/08/2023, 11:07 AMextension LoginScreen {
@MainActor class IOSLoginViewModel: ObservableObject {
private let viewModel: LoginViewModel
@Published var state: LoginState = LoginState(
usernameText: "",
passwordText: "",
isError: false,
isLoading: false,
isPasswordVisible: false,
isAuthenticated: false
)
private var handle: DisposableHandle?
init(userAuthApi: UserAuthApi) {
self.viewModel = LoginViewModel(
userAuthApi: userAuthApi,
coroutineScope: nil
)
}
func onEvent(event: LoginEvent) {
viewModel.onEvent(event: event)
}
func startObserving() {
handle = viewModel.state.subscribe(onCollect: { state in
if let state = state {
self.state = state
}
})
}
func dispose() {
handle?.dispose()
}
}
}
mohamed rejeb
10/08/2023, 11:08 AMis
to check the objectsMarc
10/08/2023, 11:09 AMSecureField(
text: Binding(get: { viewModel.state.passwordText }, set: { value in
viewModel.onEvent(event: .ChangePasswordText(password: value))
}),
label: {
Text("Passwort")
}
)
.padding()
.background(Color(.systemGray6))
.clipShape(RoundedRectangle(cornerRadius: 5.0))
.padding(.bottom)
.textContentType(.password)
struct LoginScreen: View {
@ObservedObject var viewModel: IOSLoginViewModel
init(userAuthApi: UserAuthApi) {
self.viewModel = IOSLoginViewModel(userAuthApi: userAuthApi)
}
var body: some View {
ZStack {
VStack(alignment: .center) {
TextField(
"Benutzername",
text: Binding(get: { viewModel.state.usernameText }, set: { value in
viewModel.onEvent(event: .ChangeUsernameText(username: value))
})
)
.padding()
.background(Color(.systemGray6))
.clipShape(RoundedRectangle(cornerRadius: 5.0))
.textContentType(.username)
SecureField(
text: Binding(get: { viewModel.state.passwordText }, set: { value in
viewModel.onEvent(event: .ChangePasswordText(password: value))
}),
label: {
Text("Passwort")
}
)
.padding()
.background(Color(.systemGray6))
.clipShape(RoundedRectangle(cornerRadius: 5.0))
.padding(.bottom)
.textContentType(.password)
HStack {
Button("Login", action: {
viewModel.onEvent(event: .SubmitLogin())
})
.padding()
.frame(width: .defaultWidth / 2, height: .defaultHeight)
.background(.blue)
.foregroundColor(.primary)
.clipShape(RoundedRectangle(cornerRadius: 5.0))
}
.frame(
maxWidth: .infinity,
alignment: .leading
)
}
.padding()
.onAppear() {
viewModel.startObserving()
}
.onDisappear() {
viewModel.dispose()
}
}
}
}
struct LoginScreen_Previews: PreviewProvider {
static var previews: some View {
LoginScreen(userAuthApi: AppModule().userAuthApi)
}
}
streetsofboston
10/08/2023, 12:47 PMobject
is accessed through a static/shared reference:
https://kotlinlang.org/docs/native-objc-interop.html#kotlin-singletons
Try adding the .shared
property and see if that worksMarc
10/08/2023, 12:51 PMstreetsofboston
10/08/2023, 12:52 PMMarc
10/08/2023, 12:55 PMViktor Nyblom
10/09/2023, 1:39 AMusernameText
and passwordText
to ""
, like you say you want to. In the last statement you copy the previous value, including the previous usernameText
and passwordText
.Marc
10/09/2023, 3:10 AMViktor Nyblom
10/09/2023, 3:27 AMMarc
10/09/2023, 4:30 AMNicolas Picon
10/09/2023, 5:06 AMSubmitLogin
is an object, is there a constructor to invoke? Try with viewModel.onEvent(event: LoginEvent.SubmitLogin)
Marc
10/09/2023, 6:05 AMviewModel.onEvent(event: .SubmitLogin.shared)