Hello guys, I'm trying to modularize KMM project. ...
# multiplatform
b
Hello guys, I'm trying to modularize KMM project. I need some advice and recommendation. So far planning to have SharedCommon and AndroidCommon. But not sure, how to implement feature modules. Navigation and ui native on ios and android
is it possible to have Android-specific screens within the
androidMain
directory, while keeping shared feature code in the
commonMain
directory, could you share any tips or best practices for achieving this structure? Thank you!
j
Which targets are you using now, is it iOS and Android? Regardless I recommend having a core common module with arguments/screen info. And then route each screen through that. I am using Circuit library for this. I am using feature modules myself in my KMP project. Core module also useful for other stuff want centralized and decoupled, like resources, formatting and such.
πŸ‘ 1
b
yes, it targets iOS and Android. Project is expanding so before that, I should structure it properly to prevent any potential future problems. Yes, I'l definitely use core/common module but what do you mean by saying "with arguments/screen info"? are you referring data classes? if you have example I would love to see check it out πŸ‘€
m
Hello yesterday i finish the same thing πŸ™‚
if you need some advices i'm here πŸ™‚
πŸ™Œ 1
c
is it possible to have Android-specific screens within the
androidMain
directory, while keeping shared feature code in the
commonMain
directory
Yes, it is possible
βœ… 1
b
hello @Maxime Vince, can I see it? it is my first time doing it with KMP project.
βœ… 1
c
You may want to learn about the `expect`/`actual` modifier. You can configure `sourceSet`s as many as you want, and specify `sourceSet`s you want to compile for specific targets (like
iosArm64
,
androidTarget
, etc.) When you build your app or library for a specific target, sourceSets that is not included in the target is not compiled.
j
@Bekzod Sorry vague about arguments/screen info. I meant something like this:
Copy code
@CommonParcelize
    data object LoginScreen: MyScreen {
        override val name: String = "Login()"
        override val arguments: ScreenArguments? = null
        override fun requireLogin(): Boolean = false
    }
ScreenArguments here is just typealias for Map<Enum, Any?> Put this into core module so all modules knows what each screen represents. And yes can mix between commonMain, iosMain, androidMain etc. I recommend however if you can having all in commonMain if you can πŸ™‚
c
commonMain
is always compiled for any targets, so you can put the common logic to
commonMain
and put Android-specific code to
androidMain
(even activities!), and put iOS-specific code to
iosMain
.
j
Sample can be found here https://slackhq.github.io/circuit/screen/ πŸ™‚ And no you dont need to use Circuit, can use other libraries like Decompose, Voyager or custom, up to you. Its just me like Circuit πŸ™‚
My module structure looks like this:
πŸ‘ 1
Ui is like design system, components etc I can re-use in any module. And core data is like network and database things. Then having separate ios and android modules to explicit split them and then in shared entrypoint I use in android and iOS app modules. Shared is the one setup like DI (Koin in my case) and creating the single host navigation structure, Firebase, Google plugins and such. Using a component structure in DI, which accessible from shared module. Then shared module glue together all the feature modules with DI as well πŸ™‚
πŸ‘ 1
b
Can you open one of feature module? They are kmp module right?
j
Yeah all having common, iOS and android
πŸ†— 1
b
Thanks you guys for quick and on point responses. Let me check/try them first and I'll tell/share the resultsπŸ™‚
j
Feel free slide in DM if you would like too, if have any additional questions. Cant promise I have time and knowledge about all of it, but can try πŸ™‚ Feels like you want same setup I am using, so just glad if I can help someone. For quite similar arch can always check https://github.com/chrisbanes/tivi. That is open source, using Circuit and similar setup like I am using πŸ™‚
b
Thank you @Joel Denke, I really appreciate itπŸ€“
j
No problem πŸ™‚ I can also add to the nice list of features, that you can mix native and KMP/CMP, bidirecitonal interop. As of example I love that I can write Kotlin code direclty communicating with native iOS SDKS, however only the ObjC ones, but its almost everyone except like CrytpoKit. We will get proper Swift interop soon from Jetbrains. This means as of example I was able to write my own video compose implmentation multiplatform, where I was using ExoPlayer on Android, AVPlayer on iOS and VLC on desktop. So mixing stuff in androidMain, iosMain, commonMain etc is no problem πŸ™‚ However if using a library dependency in commonMain, that module / library also need to support same targets as you do. If it doesnt, you can still use it, but lets say they only support Android you need to add the dependency in androidMain. So can really mix a lot here πŸ™‚
m
@Bekzod this is my project structure
j
@Maxime Vince Just out of my own curiousity, how come having androidFeatures? πŸ™‚
m
i simply create a folder which has many android modules in it. Android features modules ;
b
Hello guys @Joel Denke @Maxime Vince @Chanjung Kim, I have just finished modularising the project and here is the final result. Also added Convention Plugin. shared is serving is gateway(umbrella) to iOS side. all feature and sharedCommon are KMP modules. Thanks again for support!
πŸ™Œ 2