d

    Daniele B

    1 year ago
    As announced last week, I am now finally publishing the article about my research in KMP and Declarating UIs, using the MVI pattern. I am presenting the D-KMP architecture, which allows 85% of shared code. I hope this can bring useful elements to promote Kotlin MultiPlatform!https://twitter.com/dbaroncellimob/status/1329044480515772420?s=09
    t

    Thomas Myrden

    1 year ago
    Looking forward to reading this
    s

    spand

    1 year ago
    I skimmed it but didnt see any code. Have you published something that one could dive into ?
    d

    Daniele B

    1 year ago
    @spand you find relevant code snippets in the part 3 of the article
    s

    spand

    1 year ago
    Yeah. I knew it was a stretch but hoped for a complete sample 🙂
    t

    Thomas Myrden

    1 year ago
    Great read @Daniele B! Currently working on a project that's C++, React Native, Swift, Obj-C, Kotlin & Java. This is going to be super helpful to try and start informing/selling my peers on KMM/KMP.
    d

    Daniele B

    1 year ago
    @spand I didn't get the chance to create a sample repository, as I have been working on a full app. However, in the article you get all the relevant code you need.
    Robert Jaros

    Robert Jaros

    1 year ago
    I wonder if similar solutions are created for other languages (swift multiplatform?) ​​that may turn out better than KMP in the future?
    Ferran

    Ferran

    1 year ago
    @Daniele B In your diagram you expose
    StateFlow
    that goes from the native view model back to the different platforms. The thing is that I haven’t managed to get StateFlow and iOS working together. I assume that you have succeeded?
    d

    Daniele B

    1 year ago
    @Robert Jaros Two considerations:1) Kotlin is now de facto a multi-platform language, making any new feature available to 3 compilation targets: JVM, Native, JS. It's a huge effort, which is not trivial. 2) Swift is a language by Apple, which never had an interest in anything outside its ecosystem
    @Ferran in part 3 you can see the relevant code. The StateFlow is defined as a property of the shared ViewModel.
    Ferran

    Ferran

    1 year ago
    I’ll give it a go 👍 which coroutines version are you using, 1.4.1?
    d

    Daniele B

    1 year ago
    I am using 1.3.9-native-mt
    Ferran

    Ferran

    1 year ago
    ah! this is why
    I thought StateFlow and SharedFlow is not available in 1.3.9-native-mt
    Robert Jaros

    Robert Jaros

    1 year ago
    StateFlow was introduced in 1.3.6
    d

    Daniele B

    1 year ago
    StateFlow is available since 1.3.6, as I mentioned in the article. SharedFlow was just released this month, and it's actually a generalized version of StateFlow. But in terms of state management for the UI layer, StateFlow is exactly what we need.
    solidogen

    solidogen

    1 year ago
    great read. I tried to make a project structure like this, but I have no luck here, I try to solve errors until I give up. I would love to see some minimum compiling implementation of android+js+ios+backend targets thrown together
    Ferran

    Ferran

    1 year ago
    I was looking at SharedFlow instead of StateFlow for the
    events
    that you also express in the diagram. So that in both directions we have a reactive approach. But as SharedFlow is not in 1.3.9-native-mt I cannot use it yet. A SharedFlow is needed in my scenario because you could push two
    refresh
    actions and as far as I know stateFlow does not react if the same state is emitted twice, but SharedFlow will (also you have control on overlfow for when the user clicks on refresh like crazy…)
    solidogen

    solidogen

    1 year ago
    I think stateflow is conflated by design, so if you got refresh state, then rotated screen, view would subscribe again and get obsolete refresh state. So one-time events are not designed to be dispatched in stateflows, exactly like those livedata hacks like singleliveevent etc
    Ferran

    Ferran

    1 year ago
    yup I agree ^
    kqr

    kqr

    1 year ago
    in this architecture, how much could views differ on each platform?
    d

    Daniele B

    1 year ago
    @Ferran I am following the MVI pattern, which is based on the concept of uni-directional data flow. This removes a lot of complexity, and makes the code very simple. StateFlow is ideal for the MVI pattern. I am not sure why you are interested in a bi-directional flow. This brings much more complexity, and I am not sure it has a lot of benefits. Do you have a special use case?
    @kqr the difference is exactly the one between JetpackCompose and SwiftUI, which is very little. The concept behind is exactly the same, stateless declarative UIs. What changes in most cases is just the name of the components and how you specify the parameters. In most cases you can convert quickly by hand from one framework to the other one.
    Ferran

    Ferran

    1 year ago
    @Daniele B How do you send an event to the view model, do you call a suspend function, or you call a function that then calls a suspend function? Instead of that, with SharedFlow you can have unidirectional events from the UI and then collect the events inside the view model. This will decouple the action from the processing of the action and this gives you more control on the actions emitted, for example with the overflow you can control that only one action of the same type is emitted
    kqr

    kqr

    1 year ago
    yeah but my question was more if I would like to have different UI on each platform for whatever reason
    then I would need platform specific events if I get it right?
    d

    Daniele B

    1 year ago
    @Ferran the UI layer is simply calling the events, which are extension functions of the ViewModel. Inside the events you can then define any asynchronous logic you want, with the advantage of being fully shared across any platform. You wouldn't be able to share any logic on the UI layer side.
    @kqr the events are defined in the shared ViewModel, so both UI layers call the same event functions
    @Ferran one curiosity? are you experimenting with declarative UIs or with traditional UIs ?
    Ferran

    Ferran

    1 year ago
    @Daniele B to be honest I”m experimenting with a clean architecture kotlin native modules app, I’m not giving much attention to the UI components just yet as I’m planning to keep them as lean as possible
    non working but almost there, I need to figure out the sharedFlow and compilation issues https://github.com/zegnus/clean-architecture-kotlin-multiplatform
    d

    Daniele B

    1 year ago
    @Ferran yes, I was suspecting that. If you enter the world of declarative UIs, then most of your doubts fall. Uni-directional data flow is the way.
    Ferran

    Ferran

    1 year ago
    @Daniele B yup, its still unidirectional, my sharedFlow is not exposed, is just how I want to handle the async call internally in the class
    instead of calling a suspend function I emit an internal event to a private sharedFlow
    and I want to do that in order to have fine control on the UI spamming events
    d

    Daniele B

    1 year ago
    I am not sure I am following. Before you were talking about having a reactive approach in both directions. I don’t see the use case for a sharedFlow here.
    Ferran

    Ferran

    1 year ago
    ok so in your design, if a user clicks refresh 3 times, how many times do you refresh the data? (imagine that somehow the user manages to do that on a button)
    d

    Daniele B

    1 year ago
    Inside the Event functions, you have the full flexibility to write any logic you want. You might add a logic of exiting the function in case there has been another call in the last 1 second.
    Ferran

    Ferran

    1 year ago
    yup indeed, but that’s dealing with states and in a complex app that will add lots of complexity. With an internal sharedFlow that’s handled for you out of the box, with any event
    d

    Daniele B

    1 year ago
    You can add a flow directly inside the Event function.
    Ferran

    Ferran

    1 year ago
    ah yes, maybe! I’ll have a look
    d

    Daniele B

    1 year ago
    Maybe you are not referring to a specific functionality of SharedFlow, but rather to the standard functionality of Flow. SharedFlow is about multiple subscribers with a replay cache. I still haven’t found a very interesting use case for SharedFlow yet.
    Ferran

    Ferran

    1 year ago
    yup, I was trying to build a very simple example. What I had in mind is to disconnect all data sources by using a reactive approach. So that one entity subscribes to it and another one submits actions. In this way everybody has the same state of it regardless of who calls it
    but maybe that can be done with a stateFlow instead, I don’t know