https://kotlinlang.org logo
#multiplatform
Title
# multiplatform
m

maarten ha

05/28/2021, 6:58 PM
I’ve been trying to implement D-KMP in my project but it’s too difficult for a junior as a result I have no clue how to implement it in my project. For context I’m not an android or ios developer, I know react and have worked with react native for mobile development. I really want to make multiplatform app with a shared state between ios and android but I have no clue how to implement it or which guide I could use. What would you all suggest?
c

Colton Idle

05/28/2021, 7:05 PM
I've had luck following this official video from kotlin team that was uploaded about ~2 months ago.

https://www.youtube.com/watch?v=GcqFhoUuNNI

IIRC the gist of it is 1. download and install android studio 2. download the KMM plugin 3. Use the new project wizard from the plugin to generate
m

maarten ha

05/28/2021, 7:13 PM
the issue is that that app just renders static content, but I’m trying to make a kmm app with graphql that needs to be able to talk to the back-end. The issue that I’m having is that I want to make it easier to have a state shared between ios and android, where I can inject my data into shared and just have the ui elements in the ios and android module.
c

Colton Idle

05/28/2021, 8:14 PM
Kevin G is the expert in this space. Maybe he can help. Sorry I couldn't.
a

Arkadii Ivanov

05/29/2021, 7:55 AM
I would suggest to start playing with KMP and see how does it work. Then once basics are learned, it will be easier to apply an architecture (D-KMP is just one of them).
m

maarten ha

05/29/2021, 8:05 AM
No problem @Colton Idle, thank you for helping. Thank you for the suggestion @Arkadii Ivanov. Maybe it’s better to go through those steps first before trying to apply an architecture.
a

Arkadii Ivanov

05/29/2021, 8:22 AM
Yeah, like create a project from template, compile and run. Then try to add network calls, persistent storages, etc. You will need to check and learn corresponding libraries. Choose how you are going to handle async/multithreading things. Then choose UI frameworks: android views, jetpack compose, UIKit, SwiftUI. Try to create some simple UI.
m

maarten ha

05/29/2021, 8:36 AM
Thank you for the suggestions. I’ll try to implement the steps right away.
d

Daniele B

05/29/2021, 12:05 PM
@maarten ha which issues did you have with the D-KMP sample? The app doesn’t render static content, but takes the data from the shared data layer and view model, in the “shared” project folder. You can easily configure your own data layer and view model, taking the example from the D-KMP sample. Let me know which are the parts that you got stuck with, so that I can improve the documentation. For a beginner like you, D-KMP is probably the ideal architecture, because you don’t need to mess around with dependency injection, view models, coroutines scopes, kotlin/native concurrency issues, app lifecycles, platform-specific navigation. It’s all taken care by the architecture for you. You just need to focus on: • the platform-specific UI screens (in Compose and SwiftUI), • the shared view model (for the business logic) • the shared data layer (for the read/write operations from the different sources: webservices, db, settings, graphql, etc.)
m

maarten ha

05/29/2021, 2:34 PM
@Daniele B Thank you for the message. The biggest issue I’m having with learning it is, that it isn’t a hold my hand project and the nesting of the viewmodel files. To be honest I really want to try it out but I can’t figure out how it is working or how to apply it to my own. I know it’s still a work in progress and I’m trying to follow the sample but getting stuck on it. If I could help you with making it more accessible I would really like to help you out because it really looks promising.
a

Arkadii Ivanov

05/29/2021, 3:13 PM
You can check the TodoApp example https://github.com/JetBrains/compose-jb/tree/master/examples/todoapp It has MVI architecture and Compose/SwiftUI
It supports Android, Desktop and iOS
d

Daniele B

05/29/2021, 5:37 PM
I haven’t really written a proper documentation yet. I am planning to do it once I finish the Desktop and Web implementations. However here are some general steps I would follow to get started: 1. First of all, we start from the shared code and we define the screens of our app in the ScreenEnum.kt file, initialially just specifying the string and the navigation level. 2. After you have done this, for each screen you need to define 2 data classes: a. the data class for the screen state (extending the interface ScreenState), which you specify in the _screen_State.kt file inside the screen folder (e.g. viewmodel/screens/countrieslist/CountriesListState.kt) b. the data class for the screen parameters (extending the interface ScreenParams), which you specify in the _screen_Init.kt file inside the screen folder (e.g. viewmodel/screens/countrieslist/CountriesListInit.kt) 3. In the NavigationSettings.kt file, specify all your Navigation Level 1 items, which basically are the items that go in the main Menu (such as the bottom bar). For each Navigation Level 1 item, you need to specify the ScreenIdentifer. 4. The ScreenIdentifier requires 2 elements, the Screen Enum value and (optionally) a ScreenParams object. In the D-KMP sample we are using 2 Navigation Level 1 items, which are different instances of the same Screen Enum value “CountriesList”. Different instances means that they have different params, as you can see in the NavigationSettings.kt file of the D-KMP sample. 5. Let’s now define how the data loads in each screen. You can do that by specifying a Navigation extension function inside the _screen_Init.kt file (e.g. viewmodel/screens/countrieslist/CountriesListInit.kt), the same where you defined the the ScreenParams data class. The function takes the ScreenParams data class as its only parameter, and returns an instance of the ScreenInitSettings, where you define in initState the initial state of the screen, and in callOnInit the function to be run to load the data. 6. Give the above extension function the name of _initScreen (_e.g. initCountriesList). And specify this function in the initSettings property of the Screen Enum in the ScreenEnum.kt file. 7. Going back to the callOnInit function we specified in 5). As you can see, what this function does it to take data from the repository and update the ScreenState. 8. In the screenEvents.kt file inside the screen folder (e.g. viewmodel/screens/countrieslist/CountriesListEvents.kt), we define any event function that can be fired by inside the app. Events functions also do the same 2 operations of the “callOnInit” function: take the data from the repository and update the ScreenState. 9. Inside the datalayer folder, you define all the repository functions inside the functions folder, any data classes used by the repository functions inside the objects folder, and any function connecting to a specific datasource inside the sources folder. 10. At this point you have defined the whole shared code for your apps, and you can proceed to write the UI layer. 11. Let’s start with Android. In the composables/screen folder create a subfolder for each screen. Suffix the main screen composable file with “Screen” (e.g. CountriesListScreen). Conveniently split the code in different composables, which you keep inside the same folder. 12. Inside the composables/navigation/*screenPicker.kt* file define the list of all your Composable Screens. 13. Let’s now move to iOS. Similarly to Android, in the view/screen folder create a subfolder for each screen. Suffix the main screen view file with “Screen” (e.g. CountriesListScreen). Conveniently split the code in different views, which you keep inside the same folder. 14. Inside the views/navigation/*screenPicker.swift* file define the list of all your Composable Views. This is pretty much it. As you can see you don’t need to care about: • platform-specific view models • dependency injection • coroutines scopes • kotlin/native concurrency issues • app lifecycles • platform-specific navigation It’s all taken care by the architecture. If you need any more specific explanation, please let me know. Please bear in mind that the sample is in continuous evolution, so the code might change often in the future, but hopefully for the better. Next week there will be an update where the sample will start wrapping the native iOS NavigationLink component under the hood, so providing the native iOS framework animations when navigation from one page to another. Within a couple of weeks, also the Web and Desktop apps will be added, sharing as much Compose as possible between the Android, Desktop and Web apps.
🙌 1
m

maarten ha

05/29/2021, 7:31 PM
@Arkadii Ivanov thank you for the suggestion I'll have a look at the TodoApp example. It might be very useful since I also want to expand beyond mobile. @Daniele B thank you very much for the nice step by step instructions. When I have the time again I'll have a look at it again to implement it back into my app. When I have issues I'll let you know. Is the sample also open for pr's? Maybe if I have a better understanding I could make some kind of tutorial / guide for the architecture.
d

Daniele B

05/29/2021, 8:35 PM
@maarten ha yes, sure, you can contact me directly here on Slack via private messaging
2 Views