Summary: Cross-platform Kotlin code architecture utilizes Gradle Multiplatform modules with JVM/Android, iOS, JS, and other targets. Shared APIs reside in commonMain while platform implementations occupy androidMain/iosMain directories, bridged through expect/actual declarations. Swift/Objective‑C integration occurs through Kotlin/Native’s Obj‑C interop, while Java interop functions on the JVM. kotlinx.serialization provides multiplatform JSON/ProtoBuf support with optimization options for polymorphism and performance. Implementation challenges include dead code bundles, GC/ARC memory management, binary size, and startup overhead, addressed through established best practices. (kotlinlang.org, kotlinlang.org)

Project Setup & Gradle DSL

Gradle Multiplatform configuration begins with the kotlin-multiplatform plugin and target declarations within the kotlin {} block: jvm(), androidTarget(), iosX64(), iosArm64(), and js(IR) { browser() } (kotlinlang.org). Hierarchical source sets (commonMain, commonTest, androidMain, iosMain, jsMain) enable shared dependencies in commonMain while isolating platform-specific code (kotlinlang.org). The Gradle Kotlin DSL provides type-safe configurations and editor auto-completion, exemplified by androidTarget { compilations["main"].defaultSourceSet { dependencies { implementation("com.google.code.gson:gson:2.8.9") } } } (kotlinlang.org).

expect/actual Patterns

Platform-agnostic APIs in commonMain utilize expect fun platformLog(message: String): Unit with actual implementations in androidMain and iosMain (kotlinlang.org). Advanced patterns include typealias for cross-platform type unification and dependency injection within actual blocks for implementation swapping (medium.com). Best practices recommend minimal commonMain surface area, limiting expect declarations to core logic requirements for improved portability (carrion.dev).

Native Integration

Kotlin/Native’s Objective‑C interop generates frameworks for Xcode import. .framework generation occurs through kotlin.targets.native with KotlinMultiplatform.framework referenced in Swift projects, exposing Kotlin classes as Obj‑C types (kotlinlang.org). Memory management integrates Kotlin’s tracing GC with Objective‑C ARC, though object freezing and thread confinement require attention for cross-thread state sharing (kotlinlang.org). Pure Swift interop relies on the Obj‑C bridge, with Kotlin types imported through generated headers (github.com).

Java Interop on the JVM

JVM targets directly utilize Java libraries through commonMain or jvmMain dependencies, with null-safety wrappers and extension functions improving ergonomics (kotlinlang.org). Android Developers’ interop guidelines recommend @JvmOverloads, @JvmStatic, and @JvmField annotations for idiomatic Java APIs, with package organization mirroring Java conventions (developer.android.com).

Serialization Strategies

Shared modules incorporate kotlinx-serialization-core and kotlinx-serialization-json for cross-platform data serialization through @Serializable classes (ayfri.com). Polymorphic hierarchies register subclasses via SerializersModule { polymorphic(Base::class) { subclass(Derived::class) } } to prevent runtime errors (ayfri.com). Performance analysis indicates kotlinx.serialization exhibits approximately 10% overhead compared to Protobuf, with ProtoBuf or custom serializers recommended for performance-critical paths (github.com).

Implementation Challenges & Optimization

Dead code elimination may leave unused platform code in binaries, R8/ProGuard configuration with -keepclassannotations kotlinx.serialization.Serializable enables safe class stripping (github.com). Kotlin/Native binary size optimization utilizes link-time optimizations and binaryOptions.freeCompilerArgs += listOf("-Xgopt-in=...") for size reduction and startup improvement (stackoverflow.com). GC pauses in Kotlin/Native are minimized through allocation reduction, value types for hot code, and careful object graph freezing (kotlinlang.org).

Conclusion

Kotlin Multiplatform enables business logic sharing across Android, iOS, JVM, and other platforms through structured Gradle modules, expect/actual patterns, and native platform integration. kotlinx.serialization and robust interop layers facilitate consistent business logic deployment, while platform-specific optimizations address performance and resource considerations.