This project serves as a practical demonstration of implementing flavors in a Kotlin Multiplatform (KMP) project. Flavors in the context of KMP are used to differentiate between various build environments, configurations, or feature sets across the shared codebase. Specifically, this example showcases how to manage and utilize different build environments — namely, development and production — within a KMP project.
The use of flavors allows for the customization of the application's behavior, dependencies, and configurations without the need to duplicate code. This approach is particularly beneficial in a multiplatform scenario where consistency across platforms is crucial, yet the need for environment-specific variations exists.
In this example, you'll find how to:
- Configure build flavors in the
build.gradle.kts
files for targeting different environments. - Utilize the
gradle.properties
file to define default build configurations and how to override them via command-line options for flexible build processes. - Access and use these configurations within the shared Kotlin code to tailor the application's behavior according to the selected build flavor.
- Create custom Gradle tasks that leverage these flavors for building, installing, and running the application in the desired environment.
By the end of this project, you'll have a clear understanding of how to effectively implement and work with flavors in a Kotlin Multiplatform project, enhancing your ability to manage complex build configurations and environment-specific logic in a multiplatform context.
This section guides you through setting up your project for development and production environments.
Add the following modules to your project:
config/development
config/production
Include these modules in your project by editing settings.gradle.kts
:
include(":config:development", ":config:production")
In your gradle.properties
file, define the default flavor:
flavor=development
In composeApp/build.gradle.kts
, access the flavor
property:
val flavor: String by project
val suffix = when (flavor) {
"development" -> ".dev"
else -> ""
}
kotlin {
commonMain.dependencies {
implementation(project(":config:$flavor"))
}
}
Create a strings.xml
file for each flavor. E.g.:
config/development/androidMain/values/res/strings.xml
config/production/androidMain/values/res/strings.xml
Add a string with the name app_name
like you normally would.
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="app_name">KMP Flavor Dev</string>
</resources>
This string can now be used in AndroidManifest.xml like you normally would
android {
namespace = "com.rakangsoftware.flavors"
defaultConfig {
when (flavor) {
"development" -> resValue("string", "app_name", "KMP Flavor Dev")
else -> resValue("string", "app_name", "KMP Flavor")
}
}
}
android {
defaultConfig {
applicationIdSuffix = suffix
}
}
To create a new task for running the debug build, define the following in your build script:
tasks.register("runDebug", Exec::class) {
dependsOn("clean", "uninstallDebug", "installDebug")
commandLine(
"adb", "shell", "am", "start", "-n",
"com.rakangsoftware.flavors$suffix/com.rakangsoftware.flavors.MainActivity"
)
}
Note: Update the MainActivity
path if your starting activity is different.
To build, install, and run your application, use the following commands:
-
For development:
./gradlew runDebug -Pflavor=development
-
For production:
./gradlew runDebug -Pflavor=production
Configure run configurations for easy execution within Android Studio:
- Click the Plus (+) sign in the top left corner of the "Run/Debug Configurations" dialog.
- Choose 'Gradle'.
- Configure with the following:
- Name: Android Dev
- Tasks: :composeApp:runDebug
- Arguments: -Pflavor=development
- Gradle Project: Flavors
- Repeat the steps for creating a new configuration.
- Configure with the following:
- Name: Android Prod
- Tasks: :composeApp:runDebug
- Arguments: -Pflavor=production
- Gradle Project: Flavors
Below is a refined and detailed iOS setup guide for your README.md, designed to assist in configuring development and production environments for a Kotlin Multiplatform project:
This section outlines the steps required to configure your iOS application for different environments: Development and Production. These configurations enable you to build and run your iOS app with environment-specific settings and resources.
- Select the Target: In Xcode, select the
iosApp
root in the project navigator. Then, choose theiosApp
target on the target list to the right.
To set up your project for the Development environment, follow these steps:
-
Rename Info.plist: Rename the
iosApp/Info.plist
file toiosApp/Info-Development.plist
. This allows you to maintain separate property lists for different environments. -
Update Build Phases: Navigate to the
Build Phases
tab and locate theCompile Kotlin Framework
section. Modify the script to include the-Pflavor=development
flag:./gradlew :composeApp:embedAndSignAppleFrameworkForXcode -Pflavor=development
-
Adjust Info.plist File Setting: Under the
Build Settings
tab, find theInfo.plist File
setting within thePackaging
section. Update its value to point to the new development plist file:iosApp/Info-Development.plist
. -
Rename the Target: Change the name of the
iosApp
target toDevelopment
to clearly identify the build configuration. -
Rename Scheme: Update the scheme name to
iOS Dev
for easy identification.
For the Production environment, duplicate the Development setup with slight modifications:
-
Duplicate and Rename Target: Duplicate the
Development
target and rename the new target toProduction
. -
Create and Move Info.plist: Rename the duplicated
.plist
file toInfo-Production.plist
and ensure it is located withiniosApp
. -
Update Build Phases for Production: In the
Build Phases
of theProduction
target, adjust theCompile Kotlin Framework
script to use the production flavor:./gradlew :composeApp:embedAndSignAppleFrameworkForXcode -Pflavor=production
-
Update Info.plist File Setting for Production: Within the
Build Settings
of theProduction
target, change theInfo.plist File
underPackaging
to:iosApp/Info-Production.plist
. -
Rename Scheme: Rename the newly created scheme to
iOS Prod
for clarity.
-
Invalidate Android Studio Caches: To ensure that your changes are fully applied and to avoid potential issues, invalidate the caches in Android Studio by navigating to
File
->Invalidate Caches
-> Check all boxes -> ClickInvalidate and Restart
. -
Setup iOS Run Configurations: Adjust your iOS run configurations to reflect the Development and Production setups. This ensures that you can easily switch between environments when running your app.