Kotlin Adept Notes
2.31K subscribers
80 photos
9 videos
127 links
Канал о разработке на Kotlin и обо всем, что с ним связано
По всем вопросам и рекламе: @ajiekcx
Download Telegram
Мы в команде создаём переиспользуемые общие модули между приложениями, и общая логика ключевых модулей шарится между Android и iOS. Это, безусловно, несёт в себе много плюсов, но и добавляет много сложностей.

Например, так сложилось, что в Android все модули находятся в монорепозитории, а в iOS каждый отдельный модуль — это отдельный репозиторий из-за особенностей менеджера пакетов Swift (SPM).

Поэтому мы предоставляем общий фреймворк через SPM, который iOS-разработчики могут подключить как отдельную зависимость.

И если вы шарите код только одной библиотеки, всё достаточно просто. Но когда появляется вторая и третья библиотека, начинаются проблемы. В KMP рекомендуется использовать так называемый umbrella-модуль, чтобы не тащить рантайм KMP в каждый отдельный фреймворк.

Но это несёт в себе одну большую проблему: всё, что мы экспортируем, попадает в одно пространство имён. Соответственно, одинаково названные классы при интеропе в Objective-C будут переименованы: к одному из классов добавится нижнее подчёркивание. И изменения в одном модуле легко могут сломать другой 🙃

Мы пока полноценно не решили эту проблему, но выработали правило: обязательно указывать имя модуля для всех публичных сущностей, которые экспортируются в Objective-C. Но с приходом Swift Export проблема должна отпасть, так как там можно будет указывать отдельный импорт для каждой библиотеки.

Это далеко не единственная проблема, с которой мы столкнулись. Если тема интересна — ставьте реакции, и я напишу ещё посты по теме.

#KMP #iOS
Please open Telegram to view this post
VIEW IN TELEGRAM
👍765🔥3🤡3😎2👏1
Проблема версионирования

Продолжаем тему KMP, и прежде чем перейти к следующей проблеме, хочется поговорить о том, как мы делим наши библиотеки для предоставления общего кода в iOS.

Мы разбиваем библиотеку на две части: core и compose. В core-модуле, соответственно, лежит вся логика, а в compose — только вёрстка. При этом каждый модуль мы делим на пакеты api/internal и с помощью правила detekt запрещаем использовать публичные сущности из пакета internal.

Также мы стараемся избегать использования сторонних библиотек, кроме ключевых, таких, как Ktor, SQLDelight, но в качестве исключения мы приняли решение использовать Decompose. Это позволяет значительно упростить интеграцию с общим кодом в iOS, ведь всё, что нужно сделать — это смаппить жизненный цикл. А дальше, в зависимости от текущего состояния навигации, показываем тот или иной экран и отправляем события в компонент. Это позволяет скрыть все детали реализации и меньше страдать из-за проблем с интеропом.

Однако то, что хорошо работает на iOS, создаёт проблемы на Android, так как в публичном интерфейсе core-модуля приходится раскрывать все интерфейсы компонентов, чтобы иметь возможность обращаться к ним из ui-модуля. Хотя для интеграции модуля в Android достаточно передать верхнеуровневый компонент из core-модуля в экран, никто не мешает разработчикам обращаться к другим публичным сущностям.
Одним из решений здесь видится использование специальных аннотаций, например @InternalVisibilityAPI, которые будут предупреждать пользователя о том, что это внутренний API библиотеки.

В такой парадигме поддерживать обратную совместимость API, а тем более ABI, почти нереально. Поэтому, поскольку это внутренние библиотеки, мы приняли решение поднимать мажорную версию только в том случае, если реально ломаем точки интеграции API. Для iOS мы просто создаём задачи на доработку, где указываем, что поменялось в этом релизе и что требует обновления.

Процесс получился далёким от идеала, но пока что это работает 🙃

#KMP #iOS
Please open Telegram to view this post
VIEW IN TELEGRAM
👍282