Spec-Zone.ru › Kotlin 1.7

Обмен кодом на платформах

С помощью Kotlin Multiplatform вы можете обмениваться кодом, используя механизмы, предоставляемые Kotlin:

  • Обмен кодом между всеми платформами, используемыми в вашем проекте. Используйте его для обмена общей бизнес-логикой, которая применима ко всем платформам.

  • Обмен кодом между некоторыми платформами в вашем проекте, но не всеми. Вы можете повторно использовать большую часть кода в похожих платформах, используя иерархическую структуру. Вы можете использовать сокращения для целевых платформ для общих комбинаций платформ или настроить иерархическую структуру вручную.

Если вам необходимо получить доступ к платформам API из общего кода, используйте механизм Kotlin ожидаемых и фактических объявлений.

Обмен кодом на всех платформах

Если у вас есть бизнес-логика, общая для всех платформ, вам не нужно писать одинаковый код для каждой платформы — просто поделитесь им в общем наборе исходных файлов.

Code shared for all platforms

Все наборы исходных файлов, специфичные для платформы, по умолчанию зависят от общего набора исходных файлов. Вам не нужно вручную указывать какие-либо dependsOn связи для наборов исходных файлов по умолчанию, таких как jvmMain, macosX64Main, и другие.

Если вам необходимо получить доступ к платформам API из общего кода, используйте механизм Kotlin ожидаемых и фактических объявлений.

Обмен кодом на похожих платформах

Часто необходимо создавать несколько нативных целей, которые потенциально могут повторно использовать много общей логики и API сторонних сервисов.

Например, в типичном многоплатформенном проекте, нацеленном на iOS, есть две цели, связанные с iOS: одна для устройств iOS ARM64, другая для эмулятора x64. У них есть отдельные наборы исходных файлов, специфичные для платформы, но на практике редко требуется разный код для устройства и эмулятора, и их зависимости в основном одинаковы. Таким образом, код, специфичный для iOS, можно использовать совместно.

Очевидно, в этой настройке желательно иметь общий набор исходных файлов для двух целей iOS с кодом Kotlin/Native, который по-прежнему может напрямую вызывать любые API, общие для устройства iOS и эмулятора.

В этом случае вы можете совместно использовать код между нативными целями в проекте, используя иерархическую структуру. С Kotlin 1.6.20 она включена по умолчанию. Подробнее см. Иерархическую структуру проекта.

Существует два способа создания иерархической структуры:

  • Использовать сокращения для целей, чтобы легко создать структуру иерархии для распространённых сочетаний нативных целей.

  • Настроить иерархическую структуру вручную.

Узнайте больше о совместном использовании кода в библиотеках и использовании нативных библиотек в иерархической структуре.

Из-за известной проблемы, вы не сможете использовать функции IDE, такие как автодополнение и подсветка кода, для общего нативного набора исходных файлов в многоплатформенном проекте с поддержкой иерархической структуры, если ваш проект зависит от:

  • Многоплатформенных библиотек, которые не поддерживают иерархическую структуру.

  • Библиотеки сторонних разработчиков нативных языках, за исключением библиотек платформы, поддерживаемых по умолчанию.

Эта проблема относится только к общему нативному набору исходных файлов. IDE будет правильно поддерживать остальной код.

Узнайте, как обойти эту проблему для аналогичных наборов исходных файлов, таких как iosArm64 и iosX64.

Использовать сокращения для целей

В типичном многоплатформенном проекте с двумя целями iOS – iosArm64 и iosX64, иерархическая структура включает промежуточный набор исходных файлов (iosMain), который используется наборами исходных файлов, специфичными для платформы.

Code shared for iOS targets

Плагин kotlin-multiplatform предоставляет сокращения для целей, для создания структур для распространённых комбинаций целей.

Сокращение для цели

Цели

ios

iosArm64, iosX64

watchos

watchosArm32, watchosArm64, watchosX64

tvos

tvosArm64, tvosX64

Все сокращения создают похожие иерархические структуры в коде. Например, сокращение 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, внесите следующие изменения в скрипт сборки:

  1. Добавьте необходимую цель эмулятора *SimulatorArm64.

  2. Свяжите цель эмулятора с сокращением, используя зависимости наборов исходных файлов (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)
        }
    }
}

Настройка иерархической структуры вручную

Чтобы создать иерархическую структуру вручную, добавьте промежуточный набор исходных файлов, который содержит общий код для нескольких целей, и создайте структуру наборов исходных файлов, включая промежуточный.

Hierarchical structure

Например, если вы хотите использовать код совместно между нативными целями Linux, Windows и macOS – linuxX64M, mingwX64, и macosX64:

  1. Добавьте промежуточный набор исходных файлов desktopMain, который содержит общую логику для этих целей.

  2. Укажите иерархию наборов исходных файлов, используя отношение 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 или Android + JS + Native

  • JVM или Android + Native

  • JS + Native

  • JVM или Android + JS

  • Native

В настоящее время Kotlin не поддерживает совместное использование набора исходных файлов для следующих комбинаций:

  • Несколько целей JVM

  • Цели JVM + Android

  • Несколько целей JS

Если вам нужно получить доступ к платформ-специфическим API из общего нативного набора исходных файлов, IntelliJ IDEA поможет вам определить общие объявления, которые вы можете использовать в общем нативном коде. В других случаях используйте механизм Kotlin ожидаемых и фактических объявлений.

Использование кода в библиотеках

Благодаря иерархической структуре проекта, библиотеки также могут предоставлять общие API для подмножества целей. Когда библиотека публикуется, API её промежуточных наборов исходных файлов включается в артефакты библиотеки вместе с информацией о структуре проекта. При использовании этой библиотеки, промежуточные наборы исходных файлов вашего проекта получают доступ только к тем API библиотеки, которые доступны для целей каждого набора исходных файлов.

Например, посмотрите на следующую иерархию наборов исходных файлов из репозитория kotlinx.coroutines:

Library hierarchical structure

Набор исходных файлов 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

Что дальше?

  • Посмотрите примеры совместного использования кода с помощью механизма Kotlin определений expect и actual.

  • Узнайте больше о иерархической структуре проекта.

Последнее изменение: 06 сентября 2022
Публикация многоплатформенных библиотек Подключение к платформно-специфичным API

© 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

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API