https://kotlinlang.org logo
#ios
Title
x

xxfast

08/08/2022, 12:03 AM
Hi all, (again). Just wanted to share my approach in sharing state from a common ViewModel with kmp-native-coroutines. My viewmodel is defined
Copy code
// commonMain
class LoginViewModel(..) : ViewModel() {
  private val stateFlow: MutableStateFlow<LoginState> = MutableStateFlow(defaultState)

  val states: StateFlow<LoginState> = stateFlow.asStateFlow()
}
on ios, i have
Copy code
class LoginViewModelDelegate: ObservableObject {

  @Published var state: LoginLoginState = LoginLoginState.companion.DEFAULT
  
  private let viewModel: LoginLoginViewModel = AppModule.LoginModule().viewModel

  private var stateCollection: Task<Void, Error>? = nil

  func collect() {
    stateCollection = Task {
      let states = asyncStream(for: viewModel.statesNative)
      for try await _state in states {
        self.state = _state
      }
    }
  }

  func cancel() {
    stateCollection?.cancel()
  }
}
and the swiftUi view looks like
Copy code
struct LoginScreen: View {
  @StateObject private var viewModelDelegate = LoginViewModelDelegate()

  var body: some View {
    LoginView(
      state: viewModelDelegate.state,
      onChange: { state in
        viewModelDelegate.onChange(state: state)
      },
      onSubmit: { state in
        viewModelDelegate.onSubmit(state: state)
      }
    )
    .onAppear(perform: viewModelDelegate.collect)
    .onDisappear(perform: viewModelDelegate.cancel)
  }
}
This works, but i dont like it 🤔 Is there a way to avoid having two "ViewModel"s ( view model and the delegate) here?