BaseViewModel

abstract class BaseViewModel : BaseObservableManageableObject, ManageableViewModel

Common behavior for all view models.

This class inherits property delegates for change tracking and observing from BaseObservableManageableObject and BaseObservableObject. As a single point of interaction with the native code for both Android and iOS (and possible other platforms), view models have to provide an easy way for the native code to consume them. Thanks to the behavior described below, developers of the view models can work directly with values without asynchronicity.

Declaring properties using the property delegates adds them for mutation tracking through the changeTracking. Each change to those properties then triggers the changeTracking's willChange and didChange events.

Support for SwiftUI

In the native code that depends on a module using BaseViewModel, add the following implementation:

#warning("Import the Kotlin multiplatform framework in place of this warning.")
import Combine

extension BaseViewModel: ObservableObject {
private static var objectWillChangeKey: UInt8 = 0
public var objectWillChange: ObservableObjectPublisher {
if let publisher = objc_getAssociatedObject(self, &Self.objectWillChangeKey) as? ObservableObjectPublisher {
return publisher
}
let publisher = ObjectWillChangePublisher()
objc_setAssociatedObject(self, &Self.objectWillChangeKey, publisher, objc_AssociationPolicy.OBJC_ASSOCIATION_RETAIN)
willChange.addObserver {
publisher.send()
}
return publisher
}
}

extension BaseViewModel: Identifiable { }

Support for Jetpack Compose

For Jetpack Compose support make sure to include the multiplatformx-compose in your dependencies. Each BaseViewModel and its observable properties will be convertible to Compose State using observeAsState() function.

With AutoObserve (default)

When using the Hyperdrive Gradle plugin, once multiplatformx is enabled, each @Composable function's IR is modified to automatically observe any view model parameters.

Without AutoObserve

To access an observable property, use the observe method, passing it a property which has been declared using one of the provided property delegates. To further minimize required boilerplate, the Hyperdrive Kotlin compiler plugin generates observeX properties for each property x serving as quick access to the ObservableProperty for the given property.

@ViewModel
class SampleViewModel: BaseViewModel() {
var message: String by published("Default message")
private set
}

@Composable
fun SampleView1(viewModel: SampleViewModel) {
val observedViewModel by viewModel.observeAsState()
Text(observedViewModel.message)
}

@Composable
fun SampleView2(viewModel: SampleViewModel) {
val message by viewModel.observeMessage.observeAsState()
Text(message)
}

See also

org.brightify.hyperdrive.multiplatformx.BaseObservableObject

for basic change tracking property delegates.

org.brightify.hyperdrive.multiplatformx.BaseObservableManageableObject

for observing property delegates.

NOTE: Annotate your class with ViewModel and make it inherit BaseViewModel to mark the class for processing by the Hyperdrive Kotlin compiler plugin.

Future plans:

  • Maybe replace delegates with annotations and make the plugin replace the code during compilation. This would probably result in a better readability, but more magic behind the scenes.

  • Include required Swift code as a template in resources allowing for an easy import.

Constructors

BaseViewModel
Link copied to clipboard
fun BaseViewModel()

Functions

toString
Link copied to clipboard
open override fun toString(): String

Properties

changeTracking
Link copied to clipboard
override val changeTracking: ObservableObject.ChangeTracking
lifecycle
Link copied to clipboard
override val lifecycle: Lifecycle