Hey guy, how do share viewmodels in KMM? Knowing that Android view models have lifecycle dependent on the platform?
s
streetsofboston
10/31/2022, 3:58 PM
I did this through expect/actual.
in commonMain, declare an expect, eg CommonViewModel (with maybe a few expect funs as well).
In androidMain, actual this with an Android ViewModel (and possibly some actuals for these funs as well).
In iOS Main, just a plain class for the actual (with some actuals for these funs as well).
a
ayodele
10/31/2022, 4:05 PM
@streetsofboston Okay thanks. Will interface make sense in this context? Does actual/expect have an advantage?
s
streetsofboston
10/31/2022, 4:07 PM
I favor interfaces&implementations. But for me actua/expect worked better for ViewModel, since you can have a different/separate class hierarchy, not requiring a single (top) interface.
streetsofboston
10/31/2022, 4:09 PM
Eg, on Android, I could do
actual class KmpViewModel : ViewModel() { .....}
and on iOS
actual class KmpViewModel { ... }
and create them (not having them injected) in my native Android or iOS code.
streetsofboston
10/31/2022, 4:14 PM
More detailed:
commonMain:
Copy code
/**
* A [ViewModel] expects to be implemented by a platform specific
* implementation of a View-Model.
*/
expect abstract class ViewModel() {
/**
* This method must be called when this [ViewModel] is no longer needed.
* It cleans up its resources and cancels its scope.
*/
abstract fun onDestroy()
}
...
...
abstract class BaseViewModel(protected val scope: CoroutineScope, protected val log: Kermit): ViewModel() {
override fun onDestroy() {
log.v { "onDestroy called" }
scope.cancel()
}
...
}
androidMain:
Copy code
/**
* Android implements the [ViewModel] through its Android lifecycle [androidx.lifecycle.ViewModel].
*/
actual abstract class ViewModel : androidx.lifecycle.ViewModel() {
override fun onCleared() = onDestroy()
actual abstract fun onDestroy()
}
iosMain:
Copy code
/**
* iOS does not provide any platform-specific implementation for a [ViewModel].
*/
actual abstract class ViewModel {
actual abstract fun onDestroy()
}