当您将 Kotlin Multiplatform 添加到现有项目或创建新项目时,有多种不同的代码结构方式。通常,您会创建一个或多个 Kotlin Multiplatform 共享模块,并在 Android 和 iOS 应用中使用它们。
为了选择最适合您具体情况的方法,请考虑以下问题:
如何从 iOS 应用中使用 Kotlin 多平台模块生成的 iOS 框架?是直接集成、通过 CocoaPods 集成,还是使用 Swift 包管理器 (SwiftPM) 集成?
您是否有一个或多个 Kotlin 多平台共享模块?应该使用什么类型的伞形模块来管理这些共享模块?
回答这些问题将有助于您为项目选择最佳配置。
将 Kotlin 多平台模块连接到 iOS 应用
要在 iOS 应用中使用 Kotlin 多平台共享模块,首先需要基于该共享模块生成iOS 框架。然后,将其作为依赖项添加到 iOS 项目中。
通常有两种选择,实现方式有所不同:
本地依赖。Kotlin 构建直接与 iOS 构建交互。
远程依赖项。Kotlin 构建会生成一个 iOS 框架,然后您可以使用包管理器将其连接到 iOS 项目。
要查看所有可用的 iOS 集成选项,请参阅iOS 集成方法。
模块配置
在 Kotlin 多平台项目中,您可以使用两种模块配置选项:单个模块或多个共享模块。
单个共享模块
最简单的模块配置在项目中只包含一个共享的 Kotlin 多平台模块:
Android 应用可以像使用普通 Kotlin 模块一样使用 Kotlin 多平台共享模块。但是,iOS 无法直接使用 Kotlin,因此 iOS 应用必须依赖于 Kotlin 多平台模块生成的 iOS 框架。
多个共享模块
随着共享模块的增长,最好将其拆分成多个功能模块。这有助于避免因只有一个模块而导致的扩展性问题。
Android 应用可以直接依赖所有功能模块,或者根据需要只依赖其中的一些模块。
iOS 应用可以依赖于 Kotlin 多平台模块生成的一个框架。当使用多个模块时,需要添加一个依赖于所有已使用模块的额外模块,称为伞形模块;然后需要配置一个包含所有模块的框架,称为伞形框架。
伞形框架包包含项目的所有共享模块,并导入到 iOS 应用中。
要设置一个伞形模块,你需要添加一个单独的模块,该模块依赖于所有功能模块,并从该模块生成一个框架:
Android 应用可以依赖于伞形模块来保持一致性,也可以依赖于独立的功能模块。伞形模块通常包含有用的实用函数和依赖注入设置代码。
您可以仅将部分模块导出到主框架,通常情况下,当框架构件作为远程依赖项使用时会这样做。这样做的主要目的是为了减小最终构件的大小,确保排除自动生成的代码。
伞形框架方法的一个已知限制是,iOS 应用无法仅使用部分功能模块,而是会自动使用所有模块。如需改进此功能,请在KT-42247和KT-42250中描述您的需求。
当你在下面的示例看到 iOS 应用依赖于一个 umbrella 模块时,这意味着它也依赖于从该模块生成的 umbrella 框架。
为什么需要伞架?
存储库配置
在新建和现有的 Kotlin 多平台项目中,可以使用许多存储库配置选项,可以使用单个存储库或多个存储库的组合。
Monorepo:所有东西都在一个仓库中
一种常见的仓库配置称为单体仓库(monorepo)配置。这种方法常用于 Kotlin 多平台示例和教程中。在这种情况下,仓库包含 Android 和 iOS 应用,以及共享模块或多个模块,包括伞形模块:
通常情况下,iOS 应用会像使用普通框架一样使用 Kotlin 多平台共享模块,可以通过直接集成或 CocoaPods 集成来实现。更多详情和教程链接,请参阅“将 Kotlin 多平台模块连接到 iOS 应用” 。
如果代码库处于版本控制之下,则应用程序和共享模块的版本将相同。
当现有的 Android 和 iOS 应用已经存储在不同的存储库中时,您可以将 Kotlin 多平台部分添加到 Android 存储库或单独的存储库中,而不是将它们合并。
两个代码库:Android + 共享 | iOS
另一种项目配置是使用两个代码仓库。在这种情况下,Kotlin 多平台代码仓库包含 Android 应用和共享模块(包括 umbrella 模块),而 Xcode 项目则包含 iOS 应用:
Android 和 iOS 应用可以分别进行版本控制,而共享模块则与 Android 应用一起进行版本控制。
三个代码库:Android | iOS | 共享
另一种选择是为 Kotlin 多平台模块创建一个单独的代码仓库。在这种情况下,Android 和 iOS 应用分别存储在不同的代码仓库中,项目的共享代码可以包含多个功能模块以及 iOS 的主模块:
每个项目都可以单独进行版本控制。Kotlin 多平台模块也必须进行版本控制,并发布到 Android 或 JVM 平台。您可以独立发布功能模块,也可以只发布伞形模块,并让 Android 应用依赖于它。
与 Kotlin 多平台模块是 Android 项目一部分的项目场景相比,单独发布 Android 工件可能会给 Android 开发人员带来额外的复杂性。
当 Android 和 iOS 团队使用相同的版本化工件时,他们的版本保持一致。从团队角度来看,这避免了共享的 Kotlin 多平台代码被 Android 开发人员“拥有”的印象。对于已经发布用于功能开发的版本化内部 Kotlin 和 Swift 包的大型项目而言,发布共享的 Kotlin 工件将成为现有工作流程的一部分。
多个代码库:Android | iOS | 多个库
当需要在多个平台上的多个应用程序之间共享功能时,您可能更倾向于使用多个包含 Kotlin 多平台代码的仓库。例如,您可以将整个产品通用的日志库存储在一个单独的仓库中,并为其设置独立的版本控制。
在这种情况下,您将拥有多个 Kotlin 多平台库仓库。如果多个 iOS 应用使用不同的“库项目”子集,则每个应用都可以拥有一个额外的仓库,其中包含包含必要依赖项的伞形模块:
这里,每个库都必须进行版本控制,并发布到 Android 或 JVM 平台。应用程序和每个库可以分别进行版本控制。
代码共享工作流程
iOS 应用可以将 Kotlin 多平台共享模块生成的框架作为本地或远程依赖项使用。您可以通过在 iOS 构建中提供框架的本地路径来使用本地依赖项。在这种情况下,您无需发布框架。或者,您可以将框架打包发布到某个位置,并让 iOS 应用像使用其他第三方依赖项一样,将其作为远程依赖项使用。
本地:源分发
本地分发是指 iOS 应用无需发布即可使用 Kotlin 多平台模块框架。iOS 应用可以直接集成该框架,也可以通过 CocoaPods 集成。
当 Android 和 iOS 团队成员都想编辑共享的 Kotlin 多平台代码时,通常会使用此工作流程。iOS 开发人员需要安装 IntelliJ IDEA 或 Android Studio,并具备 Kotlin 和 Gradle 的基础知识。
在本地分发方案中,iOS 应用构建会触发 iOS 框架的生成。这意味着 iOS 开发者可以立即看到他们对 Kotlin 多平台代码所做的更改:
这种方案通常用于两种情况。首先,它可以作为单体仓库项目配置中的默认工作流程,无需发布工件。其次,除了远程工作流程之外,它还可以用于本地开发。更多详情请参阅“为本地开发设置本地依赖项” 。
当所有团队成员都准备好编辑整个项目的代码时,这种工作流程最为高效。它在修改公共部分后,涵盖了 Android 和 iOS 两部分。理想情况下,每位团队成员都应该安装 IntelliJ IDEA/Android Studio 和 Xcode,以便在修改公共代码后打开并运行 Android 和 iOS 应用。
远程:文物分发
远程分发是指使用 Swift 包管理器或 CocoaPods 发布框架构件,并供 iOS 应用使用。Android 应用可以从本地或远程方式使用该二进制依赖项。
远程分发通常用于将新技术逐步引入现有项目。它不会显著改变 iOS 开发人员的工作流程和构建过程。拥有两个或多个代码仓库的团队主要使用远程分发来存储项目代码。
首先,您可以尝试使用KMMBridge——一套能够极大简化远程分发工作流程的构建工具。当然,您也可以自行搭建类似的工作流程:
为本地开发设置本地依赖项
许多团队在采用 Kotlin 多平台技术时会选择远程分发工作流程,以确保 iOS 开发人员的开发流程保持一致。然而,在这种工作流程下,他们很难修改 Kotlin 多平台代码。我们建议设置一个额外的“本地开发”工作流程,并引入对 Kotlin 多平台模块生成的框架的本地依赖。
当开发者添加新功能时,他们会切换到使用 Kotlin 多平台模块作为本地依赖项。这样一来,他们就可以修改通用的 Kotlin 代码,立即在 iOS 上观察其行为,并调试 Kotlin 代码。功能准备就绪后,他们可以切换回远程依赖项,并相应地发布更改。他们首先将更改发布到共享模块,之后才会对应用程序进行修改。
对于远程分发工作流程,请使用 Swift 包管理器。对于本地分发工作流程,请直接集成框架。
如果您使用 CocoaPods,也可以选择使用 CocoaPods 进行本地分发工作流。您可以通过更改环境变量来切换,具体方法请参阅TouchLab 文档。