A library that allows you to share ViewModels between Android and iOS.
Warning: this is still a WIP. Initial release coming soon 😁
Add the library to your shared Kotlin module:
dependencies {
implementation("com.rickclephas.kmm:kmm-viewmodel-core:<version>")
}
Create your ViewModels almost as you would in Android:
// 1: use KMMViewModel instead of ViewModel
open class TimeTravelViewModel: KMMViewModel() {
private val clockTime = Clock.time
/**
* A [StateFlow] that emits the actual time.
*/
val actualTime = clockTime.map { formatTime(it) }
// 2: supply viewModelScope to your stateIn calls
.stateIn(viewModelScope, SharingStarted.WhileSubscribed(), "N/A")
// 3: supply viewModelScope to your MutableStateFlows
private val _travelEffect = MutableStateFlow<TravelEffect?>(viewModelScope, null)
/**
* A [StateFlow] that emits the applied [TravelEffect].
*/
val travelEffect = _travelEffect.asStateFlow()
}
You need to use viewModelScope
wherever possible to propagate state changes to iOS.
In other cases you can access the ViewModelScope.coroutineScope
property directly.
Add the library to your Android module:
dependencies {
implementation("com.rickclephas.kmm:kmm-viewmodel-core:<version>")
}
Use the view model like you would any other Android view model:
class TimeTravelFragment: Fragment(R.layout.fragment_time_travel) {
private val viewModel: TimeTravelViewModel by viewModels()
}
Note: support for Jetpack Compose is coming soon.
Add the Swift package to your project:
dependencies: [
.package(url: "https://github.com/rickclephas/KMM-ViewModel.git", from: "<version>")
]
Create a KMMViewModel.swift
file with the following contents:
import KMMViewModelCore
import shared // This should be your shared KMM module
extension Kmm_viewmodel_coreKMMViewModel: KMMViewModel { }
After that you can use your view model almost as if it were an ObservableObject
.
Just use the view model specific property wrappers and functions:
ObservableObject |
KMMViewModel |
---|---|
@StateObject |
@StateViewModel |
@ObservedObject |
@ObservedViewModel |
@EnvironmentObject |
@EnvironmentViewModel |
environmentObject(_:) |
environmentViewModel(for:) |
E.g. to use the TimeTravelViewModel
as a StateObject
:
import SwiftUI
import shared // This should be your shared KMM module
struct ContentView: View {
@StateViewModel var viewModel = TimeTravelViewModel()
}
It's also possible to subclass your view model in Swift:
import shared // This should be your shared KMM module
class TimeTravelViewModel: shared.TimeTravelViewModel {
@Published var isResetDisabled: Bool = false
}