kotlin-swift-interopedia

main

hhru/kotlin-swift-interopedia

Kotlin-Swift interopedia

Maven Central License: MIT

Мы создали этот репозиторий, чтобы помочь разработчикам, интересующимся технологией KMM, понять, как будет выглядеть описанное ими публичное API общего модуля.

В сети есть подробная документация от JetBrains
про интероп между Kotlin и Swift, однако в ней не рассматриваются подробно все возможности языка Kotlin.

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

Таблица интеропа

Как пользоваться таблицей:

  • Знак ✅ означает, что указанной фичой Kotlin-а можно спокойно пользоваться, она генерирует Swift-friendly код без необходимости доработок;
  • Знак ⚠️ означает, что либо для работы фичи требуются какие-то доработки, либо есть несоответствие между ожидаемым и реальным поведением фичи, которое не сильно мешает разработке;
  • Знак 🚫 означает, что фичой нельзя пользоваться, она генерирует не Swift-friendly код, она работает совсем не так как ожидается, и это может стать помехой в разработке.

Фича Kotlin-а Ожидание Статус Комментарий
Common
Internal modifier Internal-функции и классы не видны в Swift Так и есть, с iOS-разработчиками придётся обсуждать только публичное API общего кода
JavaDoc comments Комментарии видны в XCode ⚠️ Комментарии видны, если добавить специальный аргумент для компилятора
Data types
Primitive types Типы, объявленные в Kotlin, можно без изменений использовать в Swift ⚠️ Может требоваться маппинг для целочисленных типов данных / маппинги для Char-а
Optional (nullable) primitive types Тип, объявленный как Nullable, является таковым и на стороне Swift / Пользоваться nullable-типами можно без изменений ⚠️ Для примитивных типов требуется маппинг в специальные optional-типы / особенности с Char?
Mutable, immutable collections Сигнатуры List / MutableList / etc имеют значение в Swift-мире и тоже регулируют мутабельность ; Использование коллекций не отличается от Kotlin ⚠️ Для регулировки мутабельности используются ключевые слова let, var / Для мутабельных коллекций требуются дополнительные маппинги
Collections with primitive types Коллекции с элементами примитивных типов не требуют дополнительных маппингов ⚠️ Маппинги не требуются только для String-типа
Collections with custom types data Коллекции с элементами кастомных типов не требуют дополнительных маппингов Маппинги не требуются 👍
Unit and Nothing Типы Unit и Nothing можно использовать так же, как в Kotlin: Unit как объект или void, Nothing - нельзя создать Реальность соответствует ожиданиям 👍
Usual workflow
Top-level functions Функцию можно использовать напрямую после импорта, аналогично Kotlin-у ⚠️ Появляется класс-обёртка: UtilityKt.topLevelFunction()
Top-level val properties (readonly) Доступ к свойству можно получить напрямую после импорта, аналогично Kotlin-у / поле readonly ⚠️ Появляется класс-обёртка для доступа к свойству: UtilityKt.propertyVal
Top-level var properties (mutable) Доступ к свойству можно получить напрямую после импорта, аналогично Kotlin-у / поле mutable ⚠️ Появляется класс-обёртка для доступа к свойству: UtilityKt.propertyVar
Extension function over platform class Функцию можно использовать на объекте платформенного класса ⚠️ Появляется класс-обёртка с методом, принимающим объект нужного класса
Extension properties over platform class Доступ к свойству можно получить с помощью объекта платформенного класса ⚠️ Появляется класс-обёртка с методом, принимающим объект нужного класса
Extension properties for companion object of platform class Доступ к свойству можно получить с помощью платформенного класса 🚫 В .h-файле свойство есть, а в Swift-е не получается использовать
Extension functions over usual class Функцию можно использовать на объекте класса Реальность соответствует ожиданиям 👍
Extension properties over usual class Доступ к свойству можно получить через объект класса Реальность соответствует ожиданиям 👍
Extension properties for companion object of usual class Доступ к свойству можно получить через класс ⚠️ Доступ к свойству можно получить через объект companion
Usual class constructor Работа с конструктором не отличается от Kotlin-а Реальность соответствует ожиданиям 👍
Usual class val property (readonly) Доступ к свойству есть из объекта класса / свойство readonly Реальность соответствует ожиданиям 👍
Usual class var property (mutable) Доступ к свойству есть из объекта класса / свойство mutable Реальность соответствует ожиданиям 👍
Usual class functions Работа с функциями, объявленными внутри класса, не отличается от Kotlin-а Реальность соответствует ожиданиям 👍
Companion object Доступ к свойствам и функциям, объявленным в companion object-е, аналогичен Kotlin-у ⚠️ Доступ есть через вспомогательный объект companion
Objects Доступ к свойствам и функциям, объявленным в object-е, аналогичен Kotlin-у ⚠️ Доступ есть через вспомогательный объект shared
Function with default arguments Работа с функциями, имеющими дефолтные аргументы, аналогична Kotlin-у 🚫 Всегда приходится указывать все аргументы функции
Constructor with default arguments Работа с конструктором, имеющим дефолтные аргументы, аналогична Kotlin-у 🚫 Всегда приходится указывать все аргументы для конструктора
Classes
Abstract class Можно отнаследоваться от абстрактного класса, IDE подсказывает какие методы надо переопределить ⚠️ В IDE нет подсказок о необходимости переопределить абстрактный метод
Annotation class Аннотации можно использовать в Swift 🚫 Аннотации не попали в .h-файл
Data class Data class-ы сохраняют свои свойства после перехода в Swift ⚠️ Не все возможности data class-ов сохраняются / есть особенности с copy
Enum class Kotlin-овский enum class превратится в enum Swift-а, и можно будет использовать switch ⚠️ Не работает как ожидается. Но сгенерировался объект со статическими элементами
Inner class Можно создать инстанс inner-класса / прямого доступа к родительским свойствам и функциям нет ⚠️ Небольшие отличия в синтаксисе создания
Open class Можно наследоваться от open-класса / есть доступ к protected-полям / можно переопределять open-методы Можно переопределять и final-методы
Sealed class Корректно конвертируется в структуру, которую можно передать в switch-конструкцию и сделать exhaustive 🚫 Генерируется класс с наследниками. Передав в switch нет подсказок об exhaustive
Value class Класс попадёт в .h-файл, им можно будет пользоваться в Swift 🚫 Класс не попал в .h-файл, пользоваться нельзя
Interfaces
Interface При реализации интерфейса, IDE подставит заглушки для всего Интерфейс стал @protocol-ом. Но почему-то val-свойство превратилось в var
Sealed interface При использовании в switch IDE поможет рассмотреть все варианты 🚫 Сгенерировались отдельные протоколы, не связанные между собой
Fun interface С помощью такого протокола можно более простым синтаксисом описать лямбду 🚫 В Swift нельзя создать анонимный класс
Functions
DSL Надеемся, что DSL в Kotlin-е превратится в DSL на Swift ⚠️ Сгенерировались функции с receiver-ами, выглядит не так удобно, как хотелось бы
Function returns lambda Функция, вернувшая лямбду, работает без крашей; лямбду можно вызвать Реальность совпадает с ожиданием
Function returns primitive type Функция, возвращающая примитивный тип, работает без ошибок Реальность совпадает с ожиданием
Function with extension function as args Можно вызвать функцию так же, как в Kotlin ⚠️ Extension-функция превращается в лямбду с параметром
Function with lambda arguments Функция, принимающая в аргументах одну или несколько лямбд, нормально конвертируется в Swift Реальность совпадает с ожиданием
Function with no return type Функции, которые ничего не возвращают, можно спокойно вызвать Реальность совпадает с ожиданием
Function with value class parameter Функция появится в .h-файле и её можно будет использовать, передавая value-класс 🚫 Функция появилась в .h-файле, но аргумент value-класса развернулся в примитивы
Function with vararg parameter vararg смапился в Swift-овый variardic и используется аналогично 🚫 Не работает так, как ожидается
Functions with overloads Использование перегруженных функций ничем не отличается от Kotlin-а ⚠️ Есть особенности при использовании одинаковых имён параметров
Inline functions Инлайн-функции есть в .h-файле, их можно вызвать Реальность совпадает с ожиданием
Suspend functions Suspend-функции развернулись в удобную для Swift-конструкцию ⚠️ Транслируется в callback, экспериментально - в async / await. Но для использования в реактивных фреймворках требуются дополнительный bridge-код
Generics
Generic classes Сгенерируется класс с generic-ом, пользоваться можно как в Kotlin ⚠️ Есть некоторые особенности использования типов
Generic functions Обычная функция-generic позволяет принять аргумент любого типа 🚫 Нет автоматического вывода типа, особенности nullability
Generic interfaces Можно реализовать протокол с generic-ом после перехода в Swift 🚫 Generic-и на интерфейсах не поддерживаются
Bounded generics Ограничение типа generic-а, объявленное в Kotlin, сработает и в Swift 🚫 Ограничение не сработало
Contravariant generics При указании ключевого слова in на generic-е, сгенерируется generic со схожим поведением (контравариантный generic) 🚫 Не работает как ожидается, приходится использовать приведение типов
Covariant generics При указании ключевого слова out на generic-е, сгенерируется generic со схожим поведением (ковариантный generic) 🚫 Не работает как ожидается, приходится использовать приведение типов
Star projection Сгенерируется generic со схожим поведением (in Nothing / out Any?) 🚫 Не работает как ожидается, приходится использовать приведение типов
Reified functions Функции с reified нормально вызываются из Swift + работают ожидаемым образом 🚫 В рантайме функция крашится

Полезные ссылки

Description

  • Swift Tools
View More Packages from this Author

Dependencies

  • None
Last updated: Sat Nov 30 2024 17:47:34 GMT-1000 (Hawaii-Aleutian Standard Time)