Kotlin Multiplatform in Practice: Sharing Business Logic Across Platforms

For a client building both iOS and Android apps for an insurance quoting product, the core logic — premium calculation, eligibility rules, form validation — was complex enough that maintaining two parallel implementations in Swift and Kotlin was a real bug-parity risk. We used Kotlin Multiplatform to write that logic once in a shared module, keeping native SwiftUI and Jetpack Compose UI layers on each platform rather than trying to share UI too.
The shared module compiles to a Kotlin/JVM artifact for Android and, via Kotlin/Native, to an XCFramework consumable from Swift. Getting that XCFramework build reliably into an Xcode project took more setup than expected — we ended up scripting the build via a Gradle task invoked from an Xcode build phase, since the tooling wasn't yet as turnkey as CocoaPods integration for a normal Swift package.
Coroutines-based async code on the shared side needed a translation layer for Swift consumption, since Swift's async/await doesn't natively understand Kotlin suspend functions. We used the SKIE compiler plugin, which generates Swift-native async signatures instead of the default callback-based bridging, and it meaningfully cleaned up the calling code on the iOS side.
Roughly 30% of the codebase ended up shared — the quoting engine, API client, and data models — while UI, navigation, and platform-specific integrations like Apple Pay and Google Pay stayed native. That ratio felt right for this project; pushing for a higher shared percentage by sharing UI logic through Compose Multiplatform was tempting but would have fought against the client's requirement for platform-idiomatic UI and animations.
The net result after a year in production: platform parity bugs in the shared logic essentially disappeared, since there's only one implementation to get wrong, but debugging crashes that cross the Kotlin/Native-to-Swift boundary took real investment in learning Kotlin/Native's stack trace format, which doesn't map cleanly onto standard iOS crash reporting tools like Crashlytics without extra symbolication work.

