Взаимодействие со Swift/Objective-C
Kotlin/Native обеспечивает косвенное взаимодействие со Swift через Objective-C. В этом документе рассказывается, как использовать объявления Kotlin в коде Swift/Objective-C и объявления Objective-C в коде Kotlin.
Вам также могут пригодиться следующие ресурсы:
Kotlin-Swift interopedia — подборка примеров использования объявлений Kotlin в коде Swift.
Раздел Интеграция со Swift/Objective-C ARC, в котором подробно рассматривается взаимодействие трассирующего сборщика мусора Kotlin и ARC в Objective-C.
Импорт библиотек Swift/Objective-C в Kotlin
Библиотеки и фреймворки Objective-C можно использовать в коде Kotlin, если они правильно добавлены в сборку (системные фреймворки импортируются по умолчанию). Подробнее см.:
Библиотеку Swift можно использовать в коде Kotlin, если её API экспортируется в Objective-C с помощью @objc. Модули, написанные только на Swift, пока не поддерживаются.
Использование Kotlin в Swift/Objective-C
Модули Kotlin можно использовать в коде Swift/Objective-C, если скомпилировать их во фреймворк:
См. раздел Сборка конечных нативных бинарных файлов, чтобы узнать, как объявлять бинарные файлы.
Пример можно найти в примере проекта Kotlin Multiplatform.
Скрытие объявлений Kotlin от Objective-C и Swift
Чтобы сделать код Kotlin удобнее для использования в Swift/Objective-C, примените аннотацию @HiddenFromObjC, чтобы скрыть объявление Kotlin от Objective-C и Swift. Она отключает экспорт функции или свойства в Objective-C.
Вместо этого можно пометить объявления Kotlin модификатором internal, чтобы ограничить их видимость модулем компиляции. Используйте @HiddenFromObjC, если нужно скрыть объявление Kotlin от Objective-C и Swift, сохранив его видимость для других модулей Kotlin.
Использование refining в Swift
@ShouldRefineInSwift позволяет заменить объявление Kotlin обёрткой, написанной на Swift. Аннотация помечает функцию или свойство как swift_private в сгенерированном API Objective-C. Такие объявления получают префикс __, благодаря которому они становятся невидимыми в Swift.
Вы по-прежнему можете использовать эти объявления в коде Swift для создания удобного для Swift API, но они не будут предлагаться в автозаполнении Xcode.
Подробнее об уточнении объявлений Objective-C в Swift см. в официальной документации Apple.
Пример использования аннотации
@ShouldRefineInSwiftсм. в Kotlin-Swift interopedia.
Изменение имён объявлений
Чтобы не переименовывать объявления Kotlin, используйте аннотацию @ObjCName. Она указывает компилятору Kotlin использовать пользовательское имя Objective-C и Swift для аннотированного класса, интерфейса или другой сущности Kotlin:
@ObjCName(swiftName = "MySwiftArray")
class MyKotlinArray {
@ObjCName("index")
fun indexOf(@ObjCName("of") element: String): Int = TODO()
}
// Usage with the ObjCName annotations
let array = MySwiftArray()
let index = array.index(of: "element")
Добавление документации с помощью комментариев KDoc
Документация необходима для понимания любого API. Документируя общий API Kotlin, вы можете рассказать его пользователям о том, как его использовать, что следует и чего не следует делать и так далее.
При создании заголовков Objective-C комментарии KDoc из кода Kotlin преобразуются в соответствующие комментарии Objective-C. Например, следующий код Kotlin с KDoc:
/** * Prints the sum of the arguments. * Properly handles the case when the sum doesn't fit in 32-bit integer. */ fun printSum(a: Int, b: Int) = println(a.toLong() + b)
создаст заголовок Objective-C с соответствующим комментарием:
/**
* Prints the sum of the arguments.
* Properly handles the case when the sum doesn't fit in 32-bit integer.
*/
+ (void)printSumA:(int32_t)a b:(int32_t)b __attribute__((swift_name("printSum(a:b:)")));
Комментарии KDoc встраиваются в klib и извлекаются из klib в создаваемые фреймворки Apple. В результате комментарии к классам и методам отображаются, например, при автозаполнении в Xcode. Если перейти к определению функций в файле .h, вы увидите комментарии к @param, @return и аналогичным тегам.
Известные ограничения:
Документация зависимостей не экспортируется, если они не скомпилированы с параметром
-Xexport-kdoc. Библиотеки, скомпилированные с этим параметром компилятора, могут быть несовместимы с другими версиями компилятора.Комментарии KDoc в основном экспортируются без изменений, но многие блочные теги KDoc, например
@property, не поддерживаются.
При необходимости можно отключить экспорт комментариев KDoc из klib в создаваемые фреймворки Apple в блоке binaries {} файла сборки Gradle:
// build.gradle.kts
import org.jetbrains.kotlin.gradle.ExperimentalKotlinGradlePluginApi
kotlin {
iosArm64 {
binaries {
framework {
baseName = "sdk"
@OptIn(ExperimentalKotlinGradlePluginApi::class)
exportKdoc.set(false)
}
}
}
}
Сопоставления
В таблице ниже показано, как концепции Kotlin сопоставляются с концепциями Swift/Objective-C и наоборот.
«->» и «<-» указывают, что сопоставление выполняется только в одном направлении.
Kotlin |
Swift |
Objective-C |
Примечания |
|---|---|---|---|
|
|
|
|
|
|
|
|
|
Инициализатор |
Инициализатор |
|
Свойство |
Свойство |
Свойство |
|
Метод |
Метод |
Метод |
|
|
|
|
|
|
|
|
|
|
|
|
|
Расширение |
Расширение |
Элемент категории |
|
Элемент |
Метод или свойство класса |
Метод или свойство класса |
|
|
|
|
|
|
|
|
|
Примитивный тип |
Примитивный тип / |
||
Тип возвращаемого значения |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Функциональный тип |
Функциональный тип |
Тип указателя на блок |
|
Встроенные классы |
Не поддерживается |
Не поддерживается |
Классы
Перевод имен
Классы Objective-C импортируются в Kotlin под исходными именами. Протоколы импортируются как интерфейсы с суффиксом Protocol в имени, например, @protocol Foo-> interface FooProtocol. Эти классы и интерфейсы помещаются в пакет, указанный в конфигурации сборки (пакеты platform.* для предварительно настроенных системных фреймворков).
При импорте в Objective-C имена классов и интерфейсов Kotlin получают префикс. Префикс определяется именем фреймворка.
Objective-C не поддерживает пакеты во фреймворке. Если компилятор Kotlin обнаруживает во фреймворке классы Kotlin с одинаковыми именами, но из разных пакетов, он переименовывает их. Этот алгоритм пока нестабилен и может меняться между выпусками Kotlin. Чтобы обойти эту проблему, можно переименовать конфликтующие классы Kotlin во фреймворке.
Статическая привязка
При использовании класса Objective-C в исходном коде Kotlin он помечается как символ со статической привязкой. В результирующем артефакте сборки связанные символы указываются как сильные внешние ссылки.
Это означает, что приложение пытается динамически связать символы при запуске, и если они недоступны, приложение аварийно завершает работу. Сбой происходит, даже если символы никогда не использовались. Символы могут быть недоступны на определенном устройстве или в определенной версии ОС.
Чтобы обойти эту проблему и избежать ошибок «Символ не найден», используйте оболочку Swift или Objective-C, которая проверяет фактическую доступность класса. Посмотрите, как этот обходной путь реализован во фреймворке Compose Multiplatform.
Инициализаторы
Инициализатор Swift/Objective-C импортируется в Kotlin как конструктор или фабричный метод с именем create. Последнее происходит с инициализаторами, объявленными в категории Objective-C или расширении Swift, поскольку в Kotlin нет понятия конструктора расширения.
Конструкторы Kotlin импортируются в Swift/Objective-C как инициализаторы.
Сеттеры
Доступные для записи свойства Objective-C, переопределяющие свойства суперкласса, доступные только для чтения, представлены методом setFoo() для свойства foo. То же относится к свойствам протокола, доступным только для чтения, которые реализованы как изменяемые.
Функции и свойства верхнего уровня
Функции и свойства Kotlin верхнего уровня доступны как члены специальных классов. Каждый файл Kotlin преобразуется в такой класс, например:
// MyLibraryUtils.kt
package my.library
fun foo() {}
Затем функцию foo() можно вызвать из Swift следующим образом:
MyLibraryUtilsKt.foo()
Подборку примеров доступа к объявлениям Kotlin верхнего уровня см. в Kotlin-Swift interopedia:
Перевод имен методов
Как правило, метки аргументов Swift и части селекторов Objective-C сопоставляются с именами параметров Kotlin. Эти понятия имеют разную семантику, поэтому иногда методы Swift/Objective-C могут импортироваться с конфликтующей сигнатурой Kotlin. В этом случае конфликтующие методы можно вызывать из Kotlin с помощью именованных аргументов, например:
[player moveTo:LEFT byMeters:17] [player moveTo:UP byInches:42]
В Kotlin это выглядит так:
player.moveTo(LEFT, byMeters = 17) player.moveTo(UP, byInches = 42)
Ниже показано, как функции kotlin.Any сопоставляются со Swift/Objective-C:
Kotlin |
Swift |
Objective-C |
|---|---|---|
|
|
|
|
|
|
|
|
|
Пример с классами данных см. в Kotlin-Swift interopedia.
Вместо переименования объявления Kotlin с помощью аннотации @ObjCName можно задать более идиоматичное имя в Swift или Objective-C.
Ошибки и исключения
Все исключения Kotlin являются непроверяемыми, то есть ошибки перехватываются во время выполнения. Однако в Swift есть только проверяемые ошибки, обрабатываемые во время компиляции. Поэтому, если код Swift или Objective-C вызывает метод Kotlin, который выбрасывает исключение, метод Kotlin следует снабдить аннотацией @Throws, указав список классов исключений, которые «ожидаются».
При компиляции в фреймворк Swift/Objective-C функции, не являющиеся suspend, которые имеют или наследуют аннотацию @Throws, представляются как методы, возвращающие NSError*, в Objective-C и как методы throws в Swift. Представления функций suspend всегда включают параметр NSError*/Error в обработчике завершения.
Если функция Kotlin, вызванная из кода Swift/Objective-C, выбрасывает исключение, являющееся экземпляром одного из классов, указанных в @Throws, или их подклассов, исключение передается как NSError. Другие исключения Kotlin, достигающие Swift/Objective-C, считаются необработанными и приводят к завершению программы.
Функции suspend без @Throws передают только CancellationException (как NSError). Функции, не являющиеся suspend, без @Throws вообще не передают исключения Kotlin.
Обратите внимание, что обратный перевод в противоположном направлении пока не реализован: методы Swift/Objective-C, выбрасывающие ошибки, не импортируются в Kotlin как методы, выбрасывающие исключения.
Перечисления
Перечисления Kotlin импортируются в Objective-C как @interface, а в Swift — как class. Эти структуры данных имеют свойства, соответствующие каждому значению перечисления. Рассмотрим следующий код Kotlin:
// Kotlin
enum class Colors {
RED, GREEN, BLUE
}
Доступ к свойствам этого класса-перечисления из Swift можно получить следующим образом:
// Swift Colors.red Colors.green Colors.blue
Чтобы использовать переменные перечисления Kotlin в операторе Swift switch, добавьте ветвь по умолчанию, чтобы избежать ошибки компиляции:
switch color {
case .red: print("It's red")
case .green: print("It's green")
case .blue: print("It's blue")
default: fatalError("No such color")
}
Приостанавливаемые функции
Приостанавливаемые функции Kotlin (suspend) представлены в создаваемых заголовочных файлах Objective-C как функции с обратными вызовами, или обработчиками завершения в терминологии Swift/Objective-C.
Начиная со Swift 5.5, функции Kotlin suspend также можно вызывать из Swift как функции async без использования обработчиков завершения. Сейчас эта возможность является экспериментальной и имеет некоторые ограничения. Подробности см. в этой задаче YouTrack.
Подробнее о механизме
async/awaitможно узнать в документации Swift.Пример и рекомендации по сторонним библиотекам, реализующим ту же функциональность, см. в Kotlin-Swift interopedia.
Расширения и элементы категорий
Элементы категорий Objective-C и расширений Swift обычно импортируются в Kotlin как расширения. Поэтому эти объявления нельзя переопределять в Kotlin, а инициализаторы расширений недоступны в качестве конструкторов Kotlin.
Расширения Kotlin для «обычных» классов Kotlin импортируются в Swift и Objective-C соответственно как расширения и элементы категорий. Расширения Kotlin для других типов рассматриваются как объявления верхнего уровня с дополнительным параметром-получателем. К таким типам относятся:
Тип Kotlin
StringТипы коллекций Kotlin и их подтипы
Типы Kotlin
interfaceПримитивные типы Kotlin
Классы Kotlin
inlineТип Kotlin
AnyФункциональные типы Kotlin и их подтипы
Классы и протоколы Objective-C
Одиночные объекты Kotlin
Одиночный объект Kotlin (созданный с помощью объявления object, включая companion object) импортируется в Swift/Objective-C как класс с единственным экземпляром.
К этому экземпляру можно обратиться через свойства shared и companion.
Для следующего кода Kotlin:
object MyObject {
val x = "Some value"
}
class MyClass {
companion object {
val x = "Some value"
}
}
Доступ к этим объектам осуществляется следующим образом:
MyObject.shared MyObject.shared.x MyClass.companion MyClass.Companion.shared
Другие примеры см. в Kotlin-Swift interopedia:
Примитивные типы
Объекты-обертки примитивных типов Kotlin сопоставляются со специальными классами Swift/Objective-C. Например, объект-обертка kotlin.Int представлен в Swift экземпляром класса KotlinInt (или экземпляром ${prefix}Int в Objective-C, где prefix — префикс имени фреймворка). Эти классы являются подклассами NSNumber, поэтому экземпляры представляют собой полноценные NSNumber, поддерживающие все соответствующие операции.
Тип NSNumber автоматически не преобразуется в примитивные типы Kotlin, если используется в качестве типа параметра или возвращаемого значения Swift/Objective-C. Причина в том, что тип NSNumber не предоставляет достаточно информации об обернутом примитивном типе значения: например, статически неизвестно, является ли NSNumber типом Byte, Boolean или Double. Поэтому примитивные значения Kotlin следует вручную приводить к NSNumber и обратно.
Строки
При передаче Kotlin String в Swift оно сначала экспортируется как объект Objective-C, после чего компилятор Swift создает еще одну копию для преобразования в Swift. Это приводит к дополнительным затратам во время выполнения.
Чтобы избежать этого, обращайтесь к строкам Kotlin в Swift напрямую как к объектам Objective-C NSString. См. пример преобразования.
NSMutableString
Класс Objective-C NSMutableString недоступен из Kotlin. Все экземпляры NSMutableString копируются при передаче в Kotlin.
Коллекции
Kotlin -> Objective-C -> Swift
При передаче коллекции Kotlin в Swift она сначала преобразуется в эквивалент Objective-C, после чего компилятор Swift копирует всю коллекцию и преобразует ее в коллекцию Swift, как описано в таблице сопоставлений.
Это последнее преобразование снижает производительность. Чтобы избежать этого, при использовании коллекций Kotlin в Swift явно приводите их к соответствующим типам Objective-C: NSDictionary, NSArray или NSSet.
См. пример преобразования
Например, следующее объявление Kotlin:
val map: Map<String, String>
В Swift оно выглядит так:
map[key]?.count ?? 0
Здесь map неявно преобразуется в Swift Dictionary, а его строковые значения сопоставляются со Swift String. Это снижает производительность.
Чтобы избежать преобразования, явно приведите map к типу Objective-C NSDictionary и обращайтесь к значениям как к NSString:
let nsMap: NSDictionary = map as NSDictionary (nsMap[key] as? NSString)?.length ?? 0
Это гарантирует, что компилятор Swift не выполнит дополнительный этап преобразования.
Swift -> Objective-C -> Kotlin
Коллекции Swift/Objective-C сопоставляются с типами Kotlin, как описано в таблице сопоставлений, за исключением NSMutableSet и NSMutableDictionary.
NSMutableSet не преобразуется в тип Kotlin MutableSet. Чтобы передать объект в Kotlin MutableSet, явно создайте коллекцию Kotlin этого типа. Для этого можно, например, использовать функцию mutableSetOf() в Kotlin, класс KotlinMutableSet в Swift или ${prefix}MutableSet в Objective-C (prefix — префикс имени фреймворка). То же относится к MutableMap.
Функциональные типы
Объекты Kotlin функционального типа (например, лямбда-выражения) преобразуются в замыкания в Swift и блоки в Objective-C. Пример функции Kotlin с лямбда-выражением см. в Kotlin-Swift interopedia.
Однако при преобразовании функции и функционального типа типы параметров и возвращаемых значений сопоставляются по-разному. Во втором случае примитивные типы сопоставляются со своими типами-обертками. Возвращаемое значение Kotlin Unit представлено соответствующим одиночным объектом Unit в Swift/Objective-C. Значение этого одиночного объекта можно получить так же, как у любого другого объекта Kotlin object. См. раздел об одиночных объектах в таблице выше.
Рассмотрим следующую функцию Kotlin:
fun foo(block: (Int) -> Unit) { ... }
В Swift она представлена следующим образом:
func foo(block: (KotlinInt) -> KotlinUnit)
Вызвать ее можно так:
foo {
bar($0 as! Int32)
return KotlinUnit()
}
Явные имена параметров в типах блоков Objective-C
Для заголовочных файлов Objective-C, экспортируемых из Kotlin, можно задавать явные имена параметров функциональных типов. При вызове функций Objective-C в блоке Objective-C автодополнение Xcode будет предлагать эти имена. Это помогает избежать предупреждений Clang в сгенерированных блоках.
Чтобы включить явные имена параметров, добавьте следующий параметр бинарной сборки в файл gradle.properties:
kotlin.native.binary.objcExportBlockExplicitParameterNames=true
Например, для следующего кода Kotlin:
// Kotlin:
fun greetUser(block: (name: String) -> Unit) = block("John")
Kotlin передает имена параметров из функциональных типов Kotlin в типы блоков Objective-C, что позволяет Xcode использовать их в подсказках:
// Objective-C:
greetUserBlock:^(NSString *name) {
// ...
};
Обобщения
Objective-C поддерживает «облегчённые обобщения», определяемые в классах и имеющие сравнительно ограниченный набор возможностей. Swift может импортировать обобщения, определённые в классах, чтобы предоставить компилятору дополнительные сведения о типах.
Поддержка возможностей обобщений в Objective-C и Swift отличается от Kotlin, поэтому при переводе неизбежно теряется часть информации, однако поддерживаемые возможности сохраняют значимую информацию.
Конкретные примеры использования обобщений Kotlin в Swift см. в Kotlin-Swift interopedia.
Ограничения
Обобщения Objective-C не поддерживают все возможности Kotlin или Swift, поэтому при переводе будет потеряна часть информации.
Обобщения можно определять только в классах, но не в интерфейсах (протоколах в Objective-C и Swift) или функциях.
Допустимость null
В Kotlin и Swift допустимость null определяется как часть спецификации типа, тогда как в Objective-C она определяется для методов и свойств типа. Например, следующий код Kotlin:
class Sample<T>() {
fun myVal(): T
}
В Swift он выглядит так:
class Sample<T>() {
fun myVal(): T?
}
Для поддержки потенциально допускающего null типа заголовок Objective-C должен определить myVal с возвращаемым значением, допускающим null.
Чтобы избежать этого, при определении обобщённых классов укажите ограничение типа, не допускающего null, если обобщённый тип никогда не должен быть null:
class Sample<T : Any>() {
fun myVal(): T
}
Это заставит заголовок Objective-C пометить myVal как не допускающий null.
Вариантность
В Objective-C обобщения можно объявлять ковариантными или контравариантными. Swift не поддерживает вариантность. При необходимости для обобщённых классов, полученных из Objective-C, можно принудительно выполнить приведение типов.
data class SomeData(val num: Int = 42) : BaseData() class GenVarOut<out T : Any>(val arg: T)
let variOut = GenVarOut<SomeData>(arg: sd) let variOutAny : GenVarOut<BaseData> = variOut as! GenVarOut<BaseData>
Ограничения
В Kotlin для обобщённого типа можно задать верхние границы. Objective-C также поддерживает эту возможность, но в более сложных случаях она недоступна и в настоящее время не поддерживается взаимодействием Kotlin с Objective-C. Исключение составляет верхняя граница, не допускающая null: она делает методы и свойства Objective-C не допускающими null.
Отключение
Чтобы заголовок фреймворка создавался без обобщений, добавьте следующий параметр компилятора в файл сборки:
binaries.framework {
freeCompilerArgs += "-Xno-objc-generics"
}
Предварительные объявления
Для импорта предварительных объявлений используйте пакеты objcnames.classes и objcnames.protocols. Например, чтобы импортировать предварительное объявление objcprotocolName, объявленное в библиотеке Objective-C с помощью library.package, используйте специальный пакет предварительных объявлений: import objcnames.protocols.objcprotocolName.
Рассмотрим две библиотеки objcinterop: одна использует objcnames.protocols.ForwardDeclaredProtocolProtocol, а другая содержит фактическую реализацию в другом пакете:
// First objcinterop library
#import <Foundation/Foundation.h>
@protocol ForwardDeclaredProtocol;
NSString* consumeProtocol(id<ForwardDeclaredProtocol> s) {
return [NSString stringWithUTF8String:"Protocol"];
}
// Second objcinterop library
// Header:
#import <Foundation/Foundation.h>
@protocol ForwardDeclaredProtocol
@end
// Implementation:
@interface ForwardDeclaredProtocolImpl : NSObject <ForwardDeclaredProtocol>
@end
id<ForwardDeclaredProtocol> produceProtocol() {
return [ForwardDeclaredProtocolImpl new];
}
Чтобы передавать объекты между двумя библиотеками, используйте явное приведение as в коде Kotlin:
// Kotlin code:
fun test() {
consumeProtocol(produceProtocol() as objcnames.protocols.ForwardDeclaredProtocolProtocol)
}
Приведение типов между сопоставленными типами
При написании кода Kotlin может потребоваться преобразовать объект из типа Kotlin в соответствующий тип Swift/Objective-C или наоборот. В этом случае можно использовать приведение as, например:
@file:Suppress("CAST_NEVER_SUCCEEDS")
import platform.Foundation.*
val nsNumber = 42 as NSNumber
val nsArray = listOf(1, 2, 3) as NSArray
val nsString = "Hello" as NSString
val string = nsString as String
IDE могут ошибочно выдавать предупреждение «Это приведение никогда не будет успешным». В таких случаях используйте аннотацию @Suppress("CAST_NEVER_SUCCEEDS").
Создание подклассов
Создание подклассов классов и интерфейсов Kotlin в Swift/Objective-C
Классы и интерфейсы Kotlin могут быть унаследованы классами и протоколами Swift/Objective-C.
Создание подклассов классов и протоколов Swift/Objective-C в Kotlin
Классы и протоколы Swift/Objective-C могут быть унаследованы классом Kotlin final. Классы Kotlin, не являющиеся final, которые наследуются от типов Swift/Objective-C, пока не поддерживаются, поэтому объявить сложную иерархию классов, наследуемых от типов Swift/Objective-C, невозможно.
Обычные методы можно переопределять с помощью ключевого слова Kotlin override. В этом случае переопределяющий метод должен иметь те же имена параметров, что и переопределяемый.
Иногда требуется переопределить инициализаторы, например при создании подкласса UIViewController. Инициализаторы, импортированные как конструкторы Kotlin, можно переопределить конструкторами Kotlin с аннотацией @OverrideInit:
class ViewController : UIViewController {
@OverrideInit constructor(coder: NSCoder) : super(coder)
...
}
Переопределяющий конструктор должен иметь те же имена и типы параметров, что и переопределяемый.
Чтобы переопределять различные методы с конфликтующими сигнатурами Kotlin, можно добавить к классу аннотацию @ObjCSignatureOverride. Эта аннотация указывает компилятору Kotlin игнорировать конфликтующие перегрузки, если от класса Objective-C унаследовано несколько функций с одинаковыми типами аргументов, но разными именами аргументов.
По умолчанию компилятор Kotlin/Native не позволяет вызывать недизайнированный инициализатор Objective-C в качестве конструктора super(). Такое поведение может быть неудобным, если в библиотеке Objective-C назначенные инициализаторы помечены неправильно. Чтобы отключить эти проверки компилятора, добавьте disableDesignatedInitializerChecks = true в файл .def библиотеки.
Возможности C
Пример использования некоторых возможностей обычного C в библиотеке, таких как небезопасные указатели, структуры и т. д., см. в разделе Взаимодействие с C.
Неподдерживаемые возможности
Некоторые возможности языка программирования Kotlin пока не сопоставлены с соответствующими возможностями Objective-C или Swift. В настоящее время следующие возможности некорректно представлены в сгенерированных заголовках фреймворка:
Встраиваемые классы (аргументы сопоставляются либо с базовым примитивным типом, либо с
id)Пользовательские классы, реализующие стандартные интерфейсы коллекций Kotlin (
List,Map,Set) и другие специальные классыПодклассы классов Objective-C, созданные на Kotlin
© 2010–2026 JetBrains s.r.o. and Kotlin Programming Language contributors
Licensed under the Apache License, Version 2.0.
https://kotlinlang.org/docs/native-objc-interop.html