Why Dependency Management Matters
Poorly managed dependencies lead to:
- Version Conflicts: Mismatched libraries causing runtime crashes.
- Slow Builds: Unoptimized configurations wasting development time.
- Scalability Issues: Difficulty adding new features or platforms.
KMP Advantages:
- Unified Codebase: Share 70%+ code across platforms.
- Centralized Control: Manage dependencies in one place.
1. Dependency Management Best Practices
1.1 Centralize Library Versions
Step 1: Declare versions in gradle.properties
:
# gradle.properties
kotlinVersion = 1.9.20
ktorVersion = 2.3.6
Code language: PHP (php)
Step 2: Reference in build.gradle.kts
:
dependencies {
implementation("org.jetbrains.kotlinx:kotlinx-coroutines-core:$kotlinVersion")
implementation("io.ktor:ktor-client-core:$ktorVersion")
}
Code language: JavaScript (javascript)
Benefits:
- Avoid duplication
- Simplify updates
1.2 Platform-Specific Dependencies
Module | Dependency | Purpose |
---|---|---|
commonMain | kotlinx-datetime | Cross-platform date handling |
androidMain | androidx.lifecycle:lifecycle-viewmodel | Android-specific UI logic |
iosMain | ktor-client-darwin | iOS networking |
Implementation:
// build.gradle.kts
kotlin {
sourceSets {
val commonMain by getting {
dependencies {
implementation("org.jetbrains.kotlinx:kotlinx-datetime:0.5.0")
}
}
val androidMain by getting {
dependencies {
implementation("androidx.lifecycle:lifecycle-viewmodel-ktx:2.7.0")
}
}
}
}
Code language: JavaScript (javascript)
2. Configuring Multiplatform Builds
2.1 Target Platform Setup
kotlin {
androidTarget() // Android
iosX64() // Intel Mac iOS Simulator
iosArm64() // M1/M2 iOS Devices
jvm("desktop") { // Desktop (Windows/macOS/Linux)
compilations.all {
kotlinOptions.jvmTarget = "17"
}
}
js(IR) { // Web
browser()
}
}
Code language: JavaScript (javascript)
2.2 Platform-Specific Code with expect
/actual
Shared Code (commonMain
)
expect fun getDeviceId(): String
Code language: JavaScript (javascript)
Android Implementation
actual fun getDeviceId(): String =
Settings.Secure.getString(context.contentResolver, Settings.Secure.ANDROID_ID)
Code language: JavaScript (javascript)
iOS Implementation
actual fun getDeviceId(): String =
UIDevice.current.identifierForVendor?.uuidString ?: ""
Code language: JavaScript (javascript)
3. Build Variants & Environment Configs
3.1 Android Product Flavors
Define in build.gradle.kts
:
android {
flavorDimensions += "environment"
productFlavors {
create("dev") {
dimension = "environment"
buildConfigField("String", "API_URL", "\"https://dev.api.com\"")
}
create("prod") {
dimension = "environment"
buildConfigField("String", "API_URL", "\"https://api.com\"")
}
}
}
Code language: JavaScript (javascript)
Access in Code:
val apiUrl = BuildConfig.API_URL
3.2 iOS Configuration via Xcode Schemes
- Create
Dev
/Prod
schemes in Xcode. - Add
API_URL
toInfo.plist
:
<key>API_URL</key>
<string>$(API_BASE_URL)</string>
Code language: HTML, XML (xml)
- Set environment variables per scheme.
4. Build Speed Optimization
4.1 Gradle Configuration
gradle.properties
:
# Parallel execution & caching
org.gradle.parallel=true
org.gradle.caching=true
kotlin.incremental=true
Code language: PHP (php)
Enable Build Cache:
./gradlew build --build-cache
4.2 Dependency Caching
Repository Setup:
dependencyResolutionManagement {
repositories {
mavenCentral()
google()
}
}
Estimated Impact:
Optimization | Build Time Reduction |
---|---|
Parallel Execution | 30-40% |
Incremental Compilation | 50-60% |
5. CI/CD Automation
5.1 GitHub Actions Workflow
name: KMP Build Pipeline
on: [push]
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-java@v3
with:
java-version: 17
- run: ./gradlew build
ios:
runs-on: macos-latest
needs: build
steps:
- uses: actions/checkout@v4
- run: ./gradlew :shared:linkDebugFrameworkIosArm64
Code language: HTTP (http)
6. Troubleshooting Common Issues
6.1 Dependency Conflicts
Force a Specific Version:
dependencies {
implementation("io.ktor:ktor-client-core") {
version { strictly("2.3.6") }
}
}
Code language: JavaScript (javascript)
Analyze Dependencies:
./gradlew :shared:dependencies > deps.txt
6.2 Cache Corruption
Clean Gradle Cache:
./gradlew cleanBuildCache
rm -rf ~/.gradle/caches
Code language: JavaScript (javascript)
Key Takeaways
- Centralize Versions: Use
gradle.properties
for consistency. - Modularize Code: Split into
commonMain
,androidMain
,iosMain
. - Optimize Builds: Enable caching and parallel execution.
- Automate CI/CD: Use GitHub Actions for cross-platform builds.
- Handle Conflicts: Use
strictly()
and dependency reports.
By implementing these strategies, you’ll reduce build times by 40-60% and ensure seamless cross-platform development. For advanced techniques, explore the official Kotlin Multiplatform docs. 🚀
Internal Links
- A Comprehensive Guide to Cross-Platform Development
- How to Switch Ruby Versions on Mac (M1, M2, M3, M4 Guide)
- Mastering Lifecycle & Performance in Compose Multiplatform | Cross-Platform Optimization Guide
External Links