Sharing Code Across Multiple Targets In Compose Multiplatform

Search for a command to run...

No comments yet. Be the first to comment.
I've been a professional software developer in the mobile space for around 15 years now. I started in the Android 2.1 / Eclipse / Ant days and iOS Objective-C days pre-ARC on Xcode 4 (if memory servic

Intro I recently learned about friendPaths as part of the Kotlin Gradle Plugin while browsing an Android Slack group. From the documentation on friendPaths: "Paths to the output directories of the friend modules whose internal declarations should be ...

If you've ever tried to compare the behavior of Row in Google's Jetpack Compose, HStack in Apple's SwiftUi, and something like display: flex in the web world, you'll see some interesting results. First, let's take a look at how HStack renders two lon...

Said another way, how to supercharge your development workflow with a debug drawer. As Android developers, we're constantly looking for ways to streamline our workflow. One often-overlooked tool that

As Jetpack Compose becomes more widely used across Android (and Multiplatform projects!), detecting regressions via tooling becomes more important to shift left and detect regressions earlier in the d

While working on my recent Compose Multiplatform app, Sync Sphere, I added Desktop as a new target. Now supporting Android, iOS, and Desktop, there was some specific code that I wanted to share and have the same between Android and iOS, but differ on Desktop.
One solution is to have the code duplicated and live under androidMain and iosMain under the shared module. However, duplicating code like that isn't a good path forward for a multitude of reasons.
Adding a shared source set between Android and iOS was a perfect solution for me here, allowing me to have one definition for both mobile platforms.
Starting with the interface and class definitions in commonMain
interface RoomRepository {
...
}
expect class RoomRepositoryImpl(
dictionary: Dictionary,
// CrashReporting is also an interface that has expect / actual
// implementations that are the same on mobile, but differ on Desktop
crashReporting: CrashReporting,
) : RoomRepository
In desktopMain, I can define my RoomRepositoryImpl like normal
actual class RoomRepositoryImpl actual constructor(
dictionary: Dictionary,
crashReporting: CrashReporting,
) : RoomRepository {
... Desktop specific implementation
}
Now on the mobile side, I created a new folder under the shared module called mobileMain
I register mobileMain as a source set in the shared module's build file like so:
val mobileMain by creating {
androidMain.dependsOn(this)
iosMain.dependsOn(this)
dependencies {
dependsOn(commonMain)
.. other dependencies
}
}
And now, I am able to put my common mobile implementation for RoomRepository that can be shared between Android and iOS!