Spec-Zone.ru › Kotlin 1.6

Добавление зависимостей iOS

Зависимости Apple SDK (такие как Foundation или Core Bluetooth) доступны в виде набора предварительно скомпилированных библиотек в проектах Kotlin Multiplatform Mobile. Они не требуют дополнительной конфигурации.

Вы также можете повторно использовать другие библиотеки и фреймворки из экосистемы iOS в ваших наборах исходного кода для iOS. Kotlin поддерживает взаимодействие с зависимостями Objective-C и Swift, если их API экспортированы в Objective-C с помощью атрибута @objc. Чисто Swift-зависимости пока не поддерживаются.

Интеграция с менеджером зависимостей CocoaPods также поддерживается с тем же ограничением — вы не можете использовать чисто Swift-пакеты.

Мы рекомендуем использовать CocoaPods для управления зависимостями iOS в проектах Kotlin Multiplatform Mobile. Управление зависимостями вручную необходимо только если вы хотите настроить процесс взаимодействия или у вас есть другие веские причины для этого.

При использовании сторонних библиотек iOS в многоплатформенных проектах с поддержкой иерархической структуры, например, с сокращениями для целей ios(), вы не сможете использовать функции IDE, такие как автодополнение и подсветка, для общего набора исходного кода iOS.

Это известная проблема, и мы работаем над её решением. Тем временем вы можете использовать этот обходной путь.

Эта проблема не относится к платформенным библиотекам, поддерживаемым из коробки.

С CocoaPods

  1. Выполните первоначальную настройку интеграции CocoaPods.

  2. Добавьте зависимость от библиотеки Pod из репозитория CocoaPods, которую вы хотите использовать, включив вызов функции pod() в build.gradle.kts (build.gradle) вашего проекта.

    kotlin {
        cocoapods {
            //..
            pod("AFNetworking") {
                version = "~> 4.0.1"
            }
        }
    }
    
        kotlin {
       cocoapods {
          //..
          pod('AFNetworking') {
             version = '~> 4.0.1'
          }
       }
    }
    

    Вы можете добавить следующие зависимости от библиотеки Pod:

    • Из репозитория CocoaPods

    • Из локально сохраненной библиотеки

    • Из пользовательского репозитория Git

    • Из архива

    • Из пользовательского репозитория Podspec

    • С пользовательскими параметрами cinterop

    • Для статической библиотеки Pod

  3. Переимпортируйте проект.

Чтобы использовать зависимость в вашем коде Kotlin, импортируйте пакет cocoapods.<library-name>. В приведённом примере это:

import cocoapods.AFNetworking.*

Без CocoaPods

Если вы не хотите использовать CocoaPods, вы можете использовать инструмент cinterop для создания Kotlin-связей для объявлений Objective-C или Swift. Это позволит вам вызывать их из кода Kotlin.

Шаги немного отличаются для библиотек и фреймворков, но идея остаётся той же.

  1. Скачайте свою зависимость.

  2. Скомпилируйте её, чтобы получить её двоичные файлы.

  3. Создайте специальный файл .def, который описывает эту зависимость для cinterop.

  4. Отредактируйте свой скрипт сборки, чтобы сгенерировать связи во время сборки.

Добавление библиотеки без CocoaPods

  1. Скачайте исходный код библиотеки и поместите его в место, откуда вы сможете ссылаться на него из своего проекта.

  2. Скомпилируйте библиотеку (авторы библиотек обычно предоставляют руководство о том, как это сделать) и получите путь к двоичным файлам.

  3. В вашем проекте создайте файл .def, например DateTools.def.

  4. Добавьте первую строку в этот файл: language = Objective-C. Если вы хотите использовать чисто C-зависимость, опустите свойство языка.

  5. Укажите значения для двух обязательных свойств:

    • headers описывает, какие заголовки будут обработаны cinterop.

    • package устанавливает имя пакета, в который должны быть помещены эти объявления.

    Например:

    headers = DateTools.h
    package = DateTools
    
  6. Добавьте информацию о взаимодействии с этой библиотекой в скрипт сборки:

    • Укажите путь к файлу .def . Этот путь можно опустить, если ваш файл .def имеет то же имя, что и cinterop, и расположен в каталоге src/nativeInterop/cinterop/.

    • Укажите cinterop, где искать заголовочные файлы, используя опцию includeDirs.

    • Настройте связывание с двоичными файлами библиотеки.

    kotlin {
        iosX64() {
            compilations.getByName("main") {
                val DateTools by cinterops.creating {
                    // Path to .def file
                    defFile("src/nativeInterop/cinterop/DateTools.def")
    
                    // Directories for header search (an analogue of the -I<path> compiler option)
                    includeDirs("include/this/directory", "path/to/another/directory")
                }
                val anotherInterop by cinterops.creating { /* ... */ }
            }
    
            binaries.all {
                // Linker options required to link to the library.
                linkerOpts("-L/path/to/library/binaries", "-lbinaryname")
            }
        }
    }
    
    kotlin {
        iosX64 {
            compilations.main {
                cinterops {
                    DateTools {
                        // Path to .def file
                        defFile("src/nativeInterop/cinterop/DateTools.def")
    
                        // Directories for header search (an analogue of the -I<path> compiler option)
                        includeDirs("include/this/directory", "path/to/another/directory")
                    }
                    anotherInterop { /* ... */ }
                }
            }
    
            binaries.all {
                // Linker options required to link to the library.
                linkerOpts "-L/path/to/library/binaries", "-lbinaryname"
            }
        }
    }
    
  7. Соберите проект.

Теперь вы можете использовать эту зависимость в своём коде Kotlin. Для этого импортируйте пакет, который вы настроили в свойстве package в файле .def. В приведённом примере это будет:

import DateTools.*

Добавление фреймворка без CocoaPods

  1. Скачайте исходный код фреймворка и поместите его в место, откуда вы сможете ссылаться на него из своего проекта.

  2. Соберите фреймворк (авторы фреймворков обычно предоставляют руководство о том, как это сделать) и получите путь к двоичным файлам.

  3. В вашем проекте создайте файл .def , например MyFramework.def.

  4. Добавьте первую строку в этот файл: language = Objective-C. Если вы хотите использовать чисто C-зависимость, опустите свойство языка.

  5. Укажите значения для этих двух обязательных свойств:

    • modules — имя фреймворка, который должен обрабатываться cinterop.

    • package — имя пакета, в который должны быть помещены эти объявления. Например:

    modules = MyFramework
    package = MyFramework
    
  6. Добавьте информацию о взаимодействии с фреймворком в скрипт сборки:

    • Укажите путь к файлу .def. Этот путь можно опустить, если ваш файл .def имеет то же имя, что и cinterop, и расположен в каталоге src/nativeInterop/cinterop/.

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

    kotlin {
        iosX64() {
            compilations.getByName("main") {
                val DateTools by cinterops.creating {
                    // Path to .def file
                    defFile("src/nativeInterop/cinterop/DateTools.def")
    
                   compilerOpts("-framework", "MyFramework", "-F/path/to/framework/")
               }
               val anotherInterop by cinterops.creating { /* ... */ }
            }
    
            binaries.all {
                // Tell the linker where the framework is located.
                linkerOpts("-framework", "MyFramework", "-F/path/to/framework/")
            }
       }
    }
    
    kotlin {
        iosX64 {
            compilations.main {
                cinterops {
                    DateTools {
                        // Path to .def file
                        defFile("src/nativeInterop/cinterop/MyFramework.def")
    
                        compilerOpts("-framework", "MyFramework", "-F/path/to/framework/")
                    }
                    anotherInterop { /* ... */ }
                }
            }
    
            binaries.all {
                // Tell the linker where the framework is located.
                linkerOpts("-framework", "MyFramework", "-F/path/to/framework/")
            }
        }
    }
    
  7. Соберите проект.

Теперь вы можете использовать эту зависимость в своём коде Kotlin. Для этого импортируйте пакет, который вы настроили в свойстве package в файле .def . В приведённом примере это будет:

import MyFramework.*

Подробнее о взаимодействии Objective-C и Swift и настройке cinterop из Gradle.

Решение для включения поддержки IDE для общего iOS-набора исходных кодов

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

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

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

Все проекты, созданные с помощью мастера проектов Kotlin Multiplatform Mobile, поддерживают иерархическую структуру, что означает, что эта проблема затрагивает их.

Чтобы включить поддержку IDE в этих случаях, вы можете обойти проблему, добавив следующий код в build.gradle.(kts) в каталоге shared вашего проекта:

val iosTarget: (String, KotlinNativeTarget.() -> Unit) -> KotlinNativeTarget =
    if (System.getenv("SDK_NAME")?.startsWith("iphoneos") == true)
        ::iosArm64
    else
        ::iosX64

iosTarget("ios")
def iosTarget
if (System.getenv("SDK_NAME")?.startsWith("iphoneos")) {
    iosTarget = kotlin.&iosArm64
} else {
    iosTarget = kotlin.&iosX64
}

В этом примере конфигурация iOS-целей зависит от переменной среды SDK_NAME, которая управляется Xcode. Для каждого сборки будет только одна iOS-цель с именем ios, которая использует iosMain набор исходных кодов. Не будет иерархии iosMain, iosArm64, и iosX64 наборов исходных кодов.

В качестве альтернативы, вы можете включить поддержку платформ зависимых библиотек в общих наборах исходных кодов. В дополнение к платформенным библиотекам, поставляемым с Kotlin/Native, этот подход также может обрабатывать пользовательские cinterop библиотеки, делая их доступными в общих наборах исходных кодов. Для включения этой функции добавьте свойство kotlin.mpp.enableCInteropCommonization=true в gradle.properties:

kotlin.mpp.enableCInteropCommonization=true

Это временное решение. Если вы являетесь автором библиотеки, рекомендуем вам включить иерархическую структуру.

С этим решением Kotlin Multiplatform tooling анализирует ваш код только по отношению к одной активной целевой платформе во время текущей сборки. Это может привести к различным ошибкам во время полной сборки со всеми целевыми платформами, и ошибки вероятнее, если ваш проект содержит другие целевые платформы помимо iOS.

Что дальше?

Ознакомьтесь с другими ресурсами по добавлению зависимостей в многоплатформенных проектах и узнайте больше о:

  • Добавление зависимостей от многоплатформенных библиотек или других многоплатформенных проектов

  • Добавление зависимостей Android

Последнее изменение: 07 апреля 2022 г.
Добавление зависимостей Android Запуск тестов с Kotlin Multiplatform

© 2010–2022 JetBrains s.r.o. and Kotlin Programming Language contributors
Licensed under the Apache License, Version 2.0.
https://kotlinlang.org/docs/multiplatform-mobile-ios-dependencies.html

Spec-Zone.ru

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