这是一篇为 My Core Pick 撰写的高质量博文。
一次编写,更快发布:使用 Kotlin Multiplatform 统一 iOS 和 Android 逻辑
我还记得那一天,我意识到我们的移动开发流程出了大问题。
我们的结账流程中有一个 Bug。
Android 团队在周二修复了它。
iOS 团队在周四修复了完全相同的 Bug。
我们花钱请两个不同的团队编写相同的逻辑、验证相同的规则并解析相同的 JSON 响应。
这感觉效率低下,因为事实确实如此。
多年来,行业的解决方案是像 Flutter 或 React Native 这样的“跨平台”框架。
但这通常意味着牺牲原生用户界面 (UI) 或处理会拖慢速度的性能桥接。
随后,Kotlin Multiplatform (KMP) 出现了。
它承诺了一些不同的东西:共享逻辑,保留原生 UI。
今天,我将带你了解为什么 KMP 是我现代移动架构的核心精选 (core pick),以及它如何让你一次编写代码并比以往更快地发布。
"一次编写,到处运行" 的问题

很长一段时间以来,移动开发的圣杯是拥有一个可以在任何地方运行的代码库。
像 React Native 或 Flutter 这样的框架试图通过渲染它们自己的 UI 来解决这个问题。
它们基本上是在说:“忽略原生的 iOS 和 Android 按钮;用我们的按钮代替。”
这对许多 App 来说效果很好。
但有时,感觉稍微有点不对劲。
动画可能不太流畅,或者 iOS 推出了框架尚不支持的新功能。
在用户体验 (UX) 方面,我一直是一个纯粹主义者。
我想让我的 iOS App 感觉 100% 像一个 iOS App,使用 SwiftUI 或 UIKit。
我想让我的 Android App 感觉 100% 像一个 Android App,使用 Jetpack Compose。
然而,我不想编写两次数据验证逻辑。
我不想编写两次网络层。
这就是 Kotlin Multiplatform 改变游戏规则的地方。
它不试图成为一个“一次编写,到处运行”的解决方案。
它是一个“一次编写逻辑,到处运行”的解决方案。
KMP 实际上是如何工作的(底层原理)

如果你刚接触 KMP,这种架构可能看起来有点神奇。
但它实际上基于非常标准的编程概念。
在 KMP 项目中,你有一个 共享模块 (Shared Module)。
这个模块包含纯 Kotlin 代码。
这是你放置“业务逻辑”的地方。
什么是业务逻辑?
当我说业务逻辑时,我指的是应用程序的大脑。
这包括向后端进行 API 调用。
它包括在本地数据库中缓存数据。
它涉及验证用户输入(例如检查电子邮件地址是否有效)。
它包括将 JSON 数据解析为 App 可以使用的对象。
编译器魔法
当你编译项目时,KMP 会做一些很棒的事情。
对于 Android App,它像往常一样将 Kotlin 代码编译成 Java 字节码。
但对于 iOS App,它将相同的 Kotlin 代码编译成 Apple 框架(使用 LLVM)。
对 Xcode 来说,你的共享 Kotlin 代码看起来就像一个 Objective-C 或 Swift 框架。
你导入它,然后调用函数。
iOS 开发者甚至不需要知道如何编写 Kotlin 就能使用它。
他们只需要看到一个名为 fetchUser() 的函数并调用它即可。
秘密武器:Expect 和 Actual

KMP 最强大的功能之一是 expect 和 actual 机制。
有时,你需要在共享代码中访问平台特定的 API。
例如,也许你需要生成一个 UUID。
Android 的处理方式与 iOS 不同。
在你的共享代码中,你可以定义一个 expect 函数。
它看起来像这样:expect fun randomUUID(): String
这基本上是在说:“我期望有一个返回字符串的函数,但我还不知道它是如何工作的。”
然后,在 Android 源码集中,你使用 Java 库编写 actual 实现。
在 iOS 源码集中,你使用 Apple 的 Foundation 库编写 actual 实现。
这允许你共享高层逻辑,同时在需要时仍能调用原生能力。
它消除了其他跨平台框架通常具有的“黑盒”限制。
我的核心精选:KMP 技术栈
如果你决定投入 KMP,你需要合适的库。
你不能直接使用 Retrofit 或 Room,因为那些是 Android 特定的 Java 库。
你需要多平台兼容的库。
以下是构建稳健 KMP 应用程序的“My Core Pick”技术栈。
网络:Ktor
Ktor 是一个用于创建微服务和 Web 应用程序的异步框架,但它能创建出色的 HTTP 客户端。
它由 JetBrains(Kotlin 的创造者)构建,并且是完全多平台的。
它可以在 iOS 和 Android 之间无缝处理 Header、身份验证和序列化。
数据库:SQLDelight
这是我最喜欢的数据库工具,毫无疑问。
SQLDelight 根据你的 SQL 语句生成类型安全的 Kotlin API。
它会在编译期间验证你的架构。
如果你在 SQL 查询中拼写错误,代码将无法编译。
它在 Android 和 iOS 上都运行在 SQLite 上,使你的数据层绝对坚固。
依赖注入:Koin
在多平台环境中,依赖注入可能很棘手。
Koin 是一个轻量级的注入框架,与 KMP 配合得非常好。
它使用特定的 DSL(领域特定语言),易于阅读。
它允许你将数据库和网络客户端直接注入到共享的 ViewModel 中。
并发:Kotlin Coroutines
过去,在 iOS 和 Android 上处理线程是回调和代理的噩梦。
Kotlin Coroutines (协程) 允许你编写看起来像同步代码的异步代码。
你可以在后台线程上运行复杂的后台操作,并将结果返回主线程,而不会阻塞 UI。
至关重要的是,这与 Swift 的 async/await 模式互操作,使得 iOS 开发者使用起来非常自然。
对团队的实际好处
为什么你应该在公司里真正提倡这种做法?
归根结底是三件事:速度、一致性和理智。
1. 迭代速度
当你添加新功能时,你只需编写一次逻辑。
你只需编写一次单元测试。
你只需要构建两次 UI。
这大大减少了开发时间,一旦团队上手,通常能减少 30-40% 左右的时间。
2. 一致性为王
我之前提到了 Bug 修复。
使用 KMP,如果你修复了共享模块中的逻辑 Bug,你就同时为两个平台修复了它。
你保证了 iOS App 和 Android App 的行为完全相同。
它们将以相同的方式计算价格。
它们将以相同的方式排序列表。
这极大地减轻了 QA 团队的认知负担。
3. 开发者的理智
Android 开发者已经喜欢上了 Kotlin。
它是一种现代、富有表现力且安全的语言。
不可否认,iOS 开发者通常对离开 Swift 犹豫不决。
但因为 KMP 将 UI 留给了 SwiftUI,iOS 开发者不会觉得自己失去了控制权。
他们仍然可以构建漂亮的、原生的界面。
他们只是不再需要编写那些解析 JSON 的无聊样板代码了。
入门指南:采用策略
那么,你该如何开始呢?
不要明天就重写整个 App。
那是灾难的配方。
KMP 设计为增量采用。
从一个小的、隔离的模块开始。
也许是你的分析逻辑。
也许是一个简单的功能,比如“新闻流”。
第 1 步:设置
使用 JetBrains 提供的 Kotlin Multiplatform Wizard。
它会为你生成文件夹结构和 Gradle 配置。
这可以节省数小时的配置麻烦。
第 2 步:迁移模型
首先将你的数据模型(你的基础类)移动到共享模块中。
这确保了两个 App 说的是同一种语言。
第 3 步:迁移网络层
一旦你的模型共享了,就迁移 API 调用。
用共享模块中的 Ktor 替换 Retrofit (Android) 和 Alamofire (iOS)。
将数据传递回原生 UI 层。
结语
移动开发领域正在发生转变。
我们正在远离 iOS 和 Android 完全是两个不同世界的孤岛式方法。
我们也正在超越基于 Web 的跨平台工具这种“妥协”方案。
Kotlin Multiplatform 找到了最佳平衡点。
它在重要的地方(UI)尊重平台差异。
它在关键的地方(逻辑)统一了相似性。
如果你想更快地发布、减少 Bug 并保持原生的外观和感觉,KMP 是前进的方向。
它绝对是我开发者工具箱中的核心精选 (Core Pick)。
在你的下一个功能中尝试一下,我保证,你绝不会想再回去把同一段代码写两遍了。