What is the current recommendation for having shar...
# multiplatform
l
What is the current recommendation for having shared viewmodel logic between Android and iOS? Is https://github.com/icerockdev/moko-mvvm a good idea? I'm interested in having automatic coroutine cancelation when viewmodel gets destroyed and easy Jetpack Compose/SwiftUI integration.
This library looks nice, but is quite dated - no active development since June, still using LiveData, Data- and ViewBinding. No support for Kotlin StateFlow or Jetpack Compose. I wonder if there are some more up-to-date alternatives.
s
I still use the official kmm-production-sample
MVVM itself is a bit outdated. I feel it's better to go with MVI / Redux
😳 1
l
I feel like there is not much difference between them and it's mostly a matter of taste. Personally for me the whole Redux terminology of Reducers, Actions etc. feels a little bloated. But probably for complex use cases it might be better structured than just doing all this inside a ViewModel.
πŸ‘ 2
s
Felt the same at first, but now I think even for smaller apps it's a really clear model. The kmm-production-sample showcases something they call NanoRedux - so no framework is needed. Just a really simple pattern and quite good to debug.
l
Ok, will take a look. Thanks for recommending it!
And I removed observeSideEffect() for simplicity. πŸ˜‰
k
https://github.com/terrakok/kmm-awesome You can also look at architecture part for other options
πŸ‘ 3
z
I am using MOKO for a small project. It works pretty well with a little modification on the DI part. It makes the architecture quite similar to the traditional MVVM Android app. But we are also researching on alternative architecture like PeopleInSpace. As Stefan suggested above, learning MVI/Redux pattern might be a good idea.
πŸ‘ 1
l
This also looks interesting, it's also a take on MVI/Redux: https://github.com/dbaroncelli/D-KMP-sample
s
I think Mitch Tabian from codingwithmitch.com used that in one of his courses.
The concept of MVI/Redux is quite simple. The most complicated thing was to learn that there are different terms for the same concept. For example in many places the thing containing your state is called a "Store". Here it seems to be called "State manager"
Also Reducers have different names. In the kmm-production-sample it's a method called "dispatch()" that does the reducing job.
☝️ 1
l
Yes, I think so. Also you pass Action objects to the reducer. In a ViewModel you would call callbacks on user actions (so UI has to know about the ViewModel).
s
But I prefer not to have a class called "Reducer" and just know that my dispatch() method does that job of the pattern, because I don't quite like the name.
The terminology of "dispatch an action" like the kmm-production-sample uses it is something I can work with πŸ˜„
The best way to learn MVI/Redux is by building an app with that πŸ˜ƒ
πŸ‘ 1
z
@Stefan Oltmann Do you think if it will be easier to learn React/Redux first, then MVI? The React/Redux tutorials seem to be more mature, while MVI in mobile is quite new πŸ€”.
s
Actually I think Redux and MVI are the same thing with different terms πŸ˜…
βœ… 1
Intents (the "I" in "MVI") and Actions the same thing.
Also Model & State are equal
So I really don't know why there are different names. It looks identical to me. But I'm not an expert. πŸ™ˆ
z
Thanks, Stefan!
s
The docs of that project also describe quite well how it works. πŸ™‚
As mentioned above I removed the the side effect stuff. It was buggy on iOS for me and also makes the whole thing even simpler. Beside that the pattern works very well on all platforms.
By the way: I also go with the Redux names because the "Indent" of MVI is very misleading if you also target Android where the name "Indent" is already used for a different thing.
πŸ‘Œ 1
l
I just found the CodingWithMitch video where he talks about the D-KMP architecture, but he only mentions he heard about it but didn't try it out yet:

https://youtu.be/L8Xq15NTuCc?t=1419β–Ύ

(He implemented platform specific ViewModels in his app)
s
Ok, I may have mixed that up, sorry. He did so much and I watched so much ^^ But the mentioned it. πŸ˜„ I got that right πŸ˜‰
Mitch also has an MVI course
k
https://kotlinlang.slack.com/archives/C3PQML5NU/p1638265712426500?thread_ts=1638199931.406200&cid=C3PQML5NU Actually, MVI on Android has been around for years...it was brought over roughly a year after React by Hannes Dorfman... I remember a local meetup where we were discussing Google's MVVM AAC libraries and saying they'll eventually do MVI like the rest of the community πŸ™‚
βœ… 1
l
The kmm-production-sample looks really interesting. There is one thing missing though: they don't handle cancelation of ongoing HTTP calls when screen loses visibility. The main
FeedStore
just takes a hardcoded
CoroutineScope(Dispatchers.Main)
which is not bound to any lifecycle. It also means it's impossible to unit test it (although this can easily be fixed by just injecting the CoroutineScope into FeedStore).
s
FeedStore operates on the main Thread because that's easier with iOS and the old Memory Model.
l
Yes
But if the Android activity is destroyed, how do you cancel the ongoing HTTP request?
Do you have a solution for this?
Or e.g. if I open a websocket for communication between the app and the server I want to close it when activity is destroyed.
s
Isn't that bound to the coroutine scope if you use Ktor?
l
No. Ktor doesn't know anything about Activities.
s
I don't know. πŸ€·β€β™‚οΈ
l
E.g. if one would use the Android ViewModel then you could use:
Copy code
private val scope = viewModelScope + coroutineContext
where
viewModelScope
automatically binds your scope to the viewmodel. So when activity is finally destroyed all coroutines get canceled.
And as
coroutineContext
you can then inject e.g.
Dispatchers.Main
s
@Konstantin Tskhovrebov can surely answer that πŸ˜‰
k
The store in our sample lives in app scope so it will be destroyed together with the app process. If you need store for activity you can inject scope to constructor, yes
πŸ™ 2
Or call 'cancel' when it is required
154 Views