Разделение кода на платформах
С помощью Kotlin Multiplatform вы можете разделять код, используя механизмы, предоставляемые Kotlin:
Разделение кода между всеми платформами в вашем проекте. Используйте это для совместного использования общей бизнес-логики, применимой ко всем платформам.
Разделение кода между некоторыми платформами в вашем проекте, но не всеми. Вы можете повторно использовать большую часть кода в похожих платформах, используя иерархическую структуру. Вы можете использовать сокращения для целей для общих комбинаций целей или создать иерархическую структуру вручную.
Если вам необходимо получить доступ к платформ-специфичным API из общего кода, используйте механизм Kotlin ожидаемых и фактических деклараций.
Разделение кода на всех платформах
Если у вас есть бизнес-логика, общая для всех платформ, вам не нужно писать одинаковый код для каждой платформы — просто поделитесь им в общем наборе исходных файлов.
Все наборы исходных файлов, специфичные для платформы, по умолчанию зависят от общего набора исходных файлов. Вам не нужно указывать какие-либо dependsOn связи вручную для наборов исходных файлов по умолчанию, таких как jvmMain, macosX64Main, и другие.
Если вам необходимо получить доступ к платформ-специфичным API из общего кода, используйте механизм Kotlin ожидаемых и фактических деклараций.
Обмен кодом на похожих платформах
Часто требуется создать несколько нативных целей, которые могут потенциально повторно использовать много общей логики и API сторонних библиотек.
Например, в типичном проекте многоплатформенной разработки, нацеленном на iOS, есть две цели, связанные с iOS: одна для устройств iOS ARM64, другая для симулятора x64. У них есть отдельные нативные наборы исходных кодов, но на практике редко возникает необходимость в разном коде для устройства и симулятора, и их зависимости во многом совпадают. Таким образом, код, специфичный для iOS, может быть общим для них.
Очевидно, в этой настройке желательно иметь общий набор исходных кодов для двух целей iOS с кодом Kotlin/Native, который все еще может напрямую вызывать любой API, общий как для устройства iOS, так и для симулятора.
В этом случае вы можете обмениваться кодом между нативными целями в вашем проекте, используя иерархическую структуру. С Kotlin 1.6.20 она включена по умолчанию. Подробнее см. Иерархическая структура проекта.
Существует два способа создания иерархической структуры:
Использование сокращений для целей для лёгкого создания иерархической структуры для распространенных комбинаций нативных целей.
Узнайте больше о обмене кодом в библиотеках и использовании нативных библиотек в иерархической структуре.
Использование сокращений для целей
В типичном многоплатформенном проекте с двумя целями iOS – iosArm64 и iosX64, иерархическая структура включает промежуточный набор исходных кодов (iosMain), который используется нативными наборами исходных кодов, специфичными для платформы.
Плагин kotlin-multiplatform предоставляет сокращения для целей, чтобы создавать структуры для общих комбинаций целей.
Сокращение для целей |
Цели |
|---|---|
|
|
|
|
|
|
Все сокращения создают похожие иерархические структуры в коде. Например, сокращение ios создаёт следующую иерархическую структуру:
kotlin {
sourceSets{
val commonMain by sourceSets.getting
val iosX64Main by sourceSets.getting
val iosArm64Main by sourceSets.getting
val iosMain by sourceSets.creating {
dependsOn(commonMain)
iosX64Main.dependsOn(this)
iosArm64Main.dependsOn(this)
}
}
}
kotlin {
sourceSets{
iosMain {
dependsOn(commonMain)
iosX64Main.dependsOn(it)
iosArm64Main.dependsOn(it)
}
}
}
Сокращения для целей и симуляторы ARM64 (Apple Silicon)
Сокращения для целей ios, watchos, и tvos не включают цели симулятора для платформ ARM64 (Apple Silicon): iosSimulatorArm64, watchosSimulatorArm64, и tvosSimulatorArm64. Если вы используете сокращения для целей и хотите скомпилировать проект для симулятора Apple Silicon, скорректируйте скрипт сборки следующим образом:
Добавьте необходимую цель симулятора
*SimulatorArm64.Свяжите цель симулятора с сокращением, используя зависимости наборов исходных кодов (
dependsOn).
kotlin {
ios()
// Add the ARM64 simulator target
iosSimulatorArm64()
val iosMain by sourceSets.getting
val iosTest by sourceSets.getting
val iosSimulatorArm64Main by sourceSets.getting
val iosSimulatorArm64Test by sourceSets.getting
// Set up dependencies between the source sets
iosSimulatorArm64Main.dependsOn(iosMain)
iosSimulatorArm64Test.dependsOn(iosTest)
}
kotlin {
ios()
// Add the ARM64 simulator target
iosSimulatorArm64()
// Set up dependencies between the source sets
sourceSets {
// ...
iosSimulatorArm64Main {
dependsOn(iosMain)
}
iosSimulatorArm64Test {
dependsOn(iosTest)
}
}
}
Настройка иерархической структуры вручную
Для ручного создания иерархической структуры добавьте промежуточный набор исходных кодов, который содержит общий код для нескольких целей, и создайте структуру наборов исходных кодов, включая промежуточный.
Например, если вы хотите обмениваться кодом между нативными целями Linux, Windows и macOS – linuxX64M, mingwX64, и macosX64:
Добавьте промежуточный набор исходных кодов
desktopMain, который содержит общую логику для этих целей.Укажите иерархию наборов исходных кодов, используя отношение
dependsOn.
kotlin{
sourceSets {
val desktopMain by creating {
dependsOn(commonMain)
}
val linuxX64Main by getting {
dependsOn(desktopMain)
}
val mingwX64Main by getting {
dependsOn(desktopMain)
}
val macosX64Main by getting {
dependsOn(desktopMain)
}
}
}
kotlin {
sourceSets {
desktopMain {
dependsOn(commonMain)
}
linuxX64Main {
dependsOn(desktopMain)
}
mingwX64Main {
dependsOn(desktopMain)
}
macosX64Main {
dependsOn(desktopMain)
}
}
}
Вы можете иметь общий набор исходных кодов для следующих комбинаций целей:
JVM + JS + Native
JVM + Native
JS + Native
JVM + JS
Native
В настоящее время Kotlin не поддерживает общий набор исходных кодов для следующих комбинаций:
Несколько целей JVM
JVM + Android цели
Несколько целей JS
Если вам нужно получить доступ к платформа-зависимым API из общего нативного набора исходных кодов, IntelliJ IDEA поможет вам определить общие объявления, которые вы можете использовать в общем нативном коде. Для других случаев используйте механизм Kotlin ожидаемых и фактических объявлений.
Обмен кодом в библиотеках
Благодаря иерархической структуре проекта, библиотеки также могут предоставлять общие API для подмножества целей. Когда библиотека опубликована, API её промежуточных наборов исходных кодов интегрируется в артефакты библиотеки вместе с информацией о структуре проекта. При использовании этой библиотеки, промежуточные наборы исходных кодов вашего проекта получают доступ только к тем API библиотеки, которые доступны для каждой цели набора исходных кодов.
Например, рассмотрите следующую иерархию наборов исходных кодов из репозитория kotlinx.coroutines:
Набор исходных кодов concurrent объявляет функцию runBlocking и компилируется для JVM и нативных целей. После обновления и публикации библиотеки kotlinx.coroutines с иерархической структурой проекта, вы можете зависеть от неё и вызывать runBlocking из набора исходных кодов, который общий для JVM и нативных целей, так как он соответствует «подписи целей» набора исходных кодов concurrent библиотеки.
Использование нативных библиотек в иерархической структуре
Вы можете использовать платформенно-зависимые библиотеки, такие как Foundation, UIKit, и POSIX в наборах исходных кодов, общих для нескольких нативных целей. Это помогает обмениваться больше нативным кодом, не ограничиваясь платформенно-зависимыми зависимостями.
С Kotlin 1.6.20, использование платформенно-зависимых библиотек доступно в общих наборах исходных кодов по умолчанию. Не требуется никаких дополнительных шагов – IntelliJ IDEA поможет вам определить общие объявления, которые вы можете использовать в общем коде. Подробнее см. Иерархическая структура проекта.
В дополнение к платформенным библиотекам, поставляемым с Kotlin/Native, этот подход также может обрабатывать настраиваемые cinterop библиотеки, делая их доступными в общих наборах исходных кодов. Чтобы включить эту поддержку, укажите дополнительный ключ kotlin.mpp.enableCInteropCommonization:
kotlin.mpp.enableCInteropCommonization=true
© 2010–2022 JetBrains s.r.o. and Kotlin Programming Language contributors
Licensed under the Apache License, Version 2.0.
https://kotlinlang.org/docs/multiplatform-share-on-platforms.html