Learn how to leverage Android ViewModels in KMM . tasks
Once I be a part of Klima over 2 years in the past, my first actual publicity to Kotlin Multiplatform. Though we did not share numerous code on completely different platforms again then, the Android app was began by Leandro a lot impressed by Jake Wharton’s Sdk Search, with the KMP being a first-class citizen. So we do not simply have cross-platform modules (eg: SQLDelight database), however our presenters are additionally (largely) cross-platform.
Quick ahead 2 years and we launched our new app: wild planet. Now our presenters are actually cross-platform and actually accessible on iOS! Sharing presenters throughout platforms is not straightforward, and that is what this text is all about.
We should begin with an necessary disclaimer: after we say presenter, it doesn’t imply that we’re speaking about MVP (Mannequin-View-Presenter)! We’re merely speaking in regards to the object chargeable for dealing with the view (i.e. rendering the view state, dealing with consumer enter), it doesn’t matter what the view is, nonetheless the pipe system water is deployed. The purpose is just not to decide on any explicit structure, and what we present right here can be utilized on MVVM, MVI, and another letter variant you may consider.
The excellence is necessary as a result of if we wish to have actually cross-platform presenters (residing in commonMain
energy provide), they can’t be one jet aircraft ViewModel
because it’s an Android particular dependency. So if we title them ViewModel
however they aren’t Jetpack ViewModel
… it turns into complicated in a short time. ViewModel
has now develop into a loaded expression. Any more, at any time when we point out it right here, it should imply Jetpack ViewModel
solely.
Having to keep away from Android references within the audio system so we are able to share them with iOS does not imply now we have to eliminate them ViewModel
, despite! There are just a few good explanation why we’d wish to hold it:
Every little thing collectively means now we have a part that may reliably energy our Android views, out of the field. Nevertheless, none of those are crucial and we are able to construct all of them ourselves. We are able to actually see how SdkSearch took benefit of lastNonConfigurationInstance
API to outlive configuration modifications with out having to depend on ViewModel
. However would not or not it’s higher if we received all of this with no further effort?
There are already plenty of completely different strategies that enable us to have cross-platform shows that can be utilized on iOS with out sacrificing ViewModel
.
DIY anticipated/precise
The primary strategy would not require any libraries and that is what Touchlab is doing in KaMPKit warehouse. They outline their very own ViewModel
as one anticipate
class:
The Android deployment of that’s trivial. One cool factor about it’s that title conflicts are resolved on the import degree as a result of they used ViewModel
names of their cross-platform abstraction class and platform-specific implementations like this:
The iOS deployment a bit of extra attention-grabbing:
We do not have a built-in scope right here, so as an alternative we create one ourselves and assure that will probably be destroyed when ViewModel
Deleted. And that is it! With simply this little glue code, now you can create a ViewModel
inside commonMain
how is the ability provide? this.
Utilizing that on iOS remains to be non-trivial, so that they wrap collectively ViewModel
in a single iOS solely ViewModel
wrapper allowed to eat one Circulation
on the iOS facet as a callback. So in the long run iOS really consumes a wrapper Later ViewModel
stay within the widespread energy provide. Writing a skinny Swift class to make issues simpler on iOS is a standard and inspired followSo no surprises right here.
This technique is nice for Android builders as a result of nothing has actually modified on the Android facet — we’re mainly translating Android ViewModel
to iOS so we are able to have a cross-platform model of it. Alternatively, we are actually tacitly embedding this Android data beneath all of the presenters, and we’re making use of this Android-style psychological mannequin of what a ViewModel
is no matter what stands out as the present notion of the remainder of the group.
This might not be an enormous deal due to what we convey from Android in the long run ViewModel
one thing fairly commonplace. Nevertheless it nonetheless provides to the cognitive load that iOS builders have to face when engaged on KMM tasks.
Rick Clephas launched this superb library just a few months in the past, and as effectively KMP-NativeCoroutines helps us to eat coroutines on iOS facet, KMM-ViewModel helps us to share ViewModel
S.
That is mainly the previous strategy became a library. It additionally begins with a cross-platform definition of a ViewModel
seems to be fairly just like what we have seen in KaMPKit. Nevertheless, the library goes past that and it additionally exhibits its personal cross-platform MutableStateFlow
carry out And SwiftUI property wrapper to assist work with ViewModel
on the iOS facet (just like KaMPKit’s wrapper).
There are comparable trade-offs right here to what KaMPKit is doing, however with the large benefit that every little thing is properly packaged into one library. If all you need is to have the ability to use Android ViewModel
on the iOS facet, particularly for brownfield apps constructed on ViewModel
this might be possibility — you may see it in motion in confetti app. However there are different methods!
Architectural Part Library
An alternative choice is to embrace libraries that present cross-platform structure elements like moko-mvvm And decompose. They’ve a considerably bigger scope than simply offering a approach to share the presenter, however they’re nonetheless able to doing that so I assumed it might make sense to say them right here.
Slack’s circuit is one other attention-grabbing possibility for the long run (they only began engaged on iOS assist), and I am certain many extra will seem. Nevertheless, adopting a framework is at all times a extra delicate determination, particularly after we are coping with a framework that’s nonetheless in beta (hopefully not too lengthy!). However even when you resolve to not go together with them, it’s best to keep watch over them and doubtlessly be taught from what they’re doing.
We now have been utilizing Retained in manufacturing for over two years now. It’s maintained by Marcello since 2019 and it has been secure for some time. It supplies a fantastic API for wrapping arbitrary objects (i.e. our cross-platform presenters) in a single ViewModel
in such a approach that we are able to make the most of every little thing it has to supply with out having to maintain any direct references to it (or something that wraps it).
It has extensions on Android elements like a ViewModel
so we are able to simply hold our object in any scope we wish. This is how you can hold a presenter in an exercise or inside a NavBackStackEntry
:
After we retain an occasion, now we have entry to a RetainedEntry
expose every little thing we want, together with viewModelScope
the savedStateHandle
and a approach to hear onClear()
Calls. You possibly can try examples of those being utilized in paperwork.
Which means that despite the fact that we are able to entry every little thing we want from ViewModel
Our presenter doesn’t have ViewModel
or another android reference in there and we are able to hold it in commonMain
there are not any anticipate
/precise
water pipe. No matter we get from Android ViewModel
solely associated to Android facet and with Retained we are able to hold all of it there with out leaking something to iOS facet.
iOS facet
This can be a considerably cleaner answer, and it retains presenters in a extra “pure” cross-platform state — iOS builders will have the ability to overview them with out having to know or summary something. Any Android-specific reference.
Nevertheless, there’s nothing right here to assist consumption on the iOS facet. That is by design as it isn’t within the scope of the library and it actually matches our wants and expectations for the way we use cross-platform presentation on iOS as a result of that is very particular. for our structure. For us, it is higher to deal with that in our personal customized (and slim) Swift class written for our particular wants.
Learn how to use a cross-platform presenter on iOS is a subject worthy of its personal article. We have realized a bit of bit about KaMPKit and KMM-ViewModel, but it surely actually will depend on the structure in place, so it is not one thing we’ll discover additional right here. Whatever the implementation particulars, our essential purpose was to discover a lean and unobtrusive approach to hold our presenters cross-platform, the place we might nonetheless leverage ViewModel
options on the Android facet and Retained has confirmed to be the most effective software for the job.
John Wick: Chapter 4 (FREE) FULLMOVIE The Super Mario Bros Movie avatar 2 Where To Watch Creed 3 Free At Home Knock at the Cabin (2023) FullMovie Where To Watch Ant-Man 3 and the Wasp: Quantumania Cocaine Bear 2023 (FullMovie) Scream 6 Full Movie