Adding "Debug" Checks To Your Compose Multiplatform Project: Android, iOS, and Desktop

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 project, Sync Sphere, which targets iOS, Android, and Desktop, I needed to add some debug checks in my application to perform some different functionality when in debug mode.
When debugging (which I mean to be developing locally), I wanted to target a different table for my remote database, so I wasn't cluttering up production data with all of my local development data.
The solution wasn't super obvious to me when I originally set out to solve this problem, so I wanted to share what ended up working for me.
In my commonMain, I defined a BuildConfig interface and an expect declaration for my BuildConfigImpl
interface BuildConfig {
fun isDebug(): Boolean
}
expect class BuildConfigImpl : BuildConfig
In my androidMain src set, it looks pretty familiar to an Android developer:
actual class BuildConfigImpl(private val applicationContext: Context) : BuildConfig {
override fun isDebug(): Boolean {
return 0 != applicationContext.applicationInfo.flags and ApplicationInfo.FLAG_DEBUGGABLE
}
}
In my iosMain src set, it looks pretty familiar to an iOS developer. (I think at least, I'm not a good iOS developer 😅)
import kotlin.experimental.ExperimentalNativeApi
actual class BuildConfigImpl() : BuildConfig {
@OptIn(ExperimentalNativeApi::class)
override fun isDebug(): Boolean {
return Platform.isDebugBinary
}
}
In my Desktop target and src set, desktopMain , I use System Properties to define a local debug flag to pass along to my application so it can be flagged true when I'm working locally.
First, I added a new property to my local gradle.properties located in my Gradle home directory (~/.gradle/gradle.properties)
systemProp.syncSphereDebug=true
Then, in my desktopApp build file, I added the following code:
tasks.withType<JavaExec>().configureEach {
systemProperty("syncSphereDebug", System.getProperty("syncSphereDebug"))
}
This allows me to now have an implementation for BuildConfigImpl for Desktop that looks like:
actual class BuildConfigImpl() : BuildConfig {
override fun isDebug(): Boolean {
val debugSystemProperty = System.getProperty("syncSphereDebug")
return debugSystemProperty?.toBoolean() ?: false
}
}
I hope this post was helpful where I covered enabling some sort of debug / local environment for providing different behavior when developing your Compose Multiplatform project!