
Лучшая архитектура KMP-приложений и когда её не использовать. Часть 2
anil 8 минут назад Лучшая архитектура KMP-приложений и когда её не использовать. Часть 2 Средний 17 мин 297 Разработка мобильных приложений * Kotlin * Android * iOS * Проектирование и рефакторинг * Туториал В первой...
<5 — 2026'da uzaya kaç SpaceX Starship fırlatması ulaşacak?
Вот важная новость с фронта ИИ: anil 8 минут назад Лучшая архитектура KMP-приложений и когда её не использовать. Часть 2 Средний 17 мин 297 Разработка мобильных приложений * Kotlin * Android * iOS * Проектирование и рефакторинг * Туториал В первой части мы разобрали философию KMP, обсудили лестницу развития проектов и выяснили, почему не стоит шарить ViewModel. Теперь давайте заглянем в код и поговорим про то, с чем столкнутся разработчики при выполнении ежедневных задач.
Это вторая, практическая, часть из двух. Здесь про то, как организованы слои, какие контракты уходят в Swift, как готовить SKIE, как устроены обработка ошибок и DI, что с модульностью, скоростью сборки и тестами. Я — Павел Присталов, Staff Engineer с почти 20-летним опытом разработки, из них 15 — в мобильной.
Технические детали
TL;DR: репозиторий-шаблон описанной архитектуры: github. com/pristalovpavel/kmp-clean-templateСлои: что где лежитData-слойВ data-слое у нас лежат API и БД для offline-first, а потоками данных управляет Repository — ровно так, как советует Google вот тут и вот тут. Переключение между источниками реализовано в двух вариантах.
Для каких-то экранов хватает упрощённого one-shot-паттернаNetworkBoundResource (классический исходник в GithubBrowserSample): сначала сеть, а при ошибке - кеш с пометкой isOldData. А там, где кеш должен обновляться сам, — полноценный реактивный Single Source of Truth: UI подписан на Flow из БД, сеть только обновляет её. В шаблоне так устроен профиль.
Domain-слойВ domain-слое имеем интерфейсы репозиториев и UseCase'ы. Реализации репозиториев, *RepositoryImpl, принадлежат data-слою и подключаются через DI: domain при этом ничего не знает о Ktor и SQLDelight, он оперирует контрактами. Именно UseCase и RepositoryImpl мы обязательно покрываем unit-тестами и подробно документируем.
Отраслевые последствия
К тестам и документации мы вернёмся немного позже. В Clean Architecture UseCase передаётся в Presentation-слой, поэтому в нашем подходе он находится на стыке миров Kotlin и Swift. И этот интерфейс критично важно продумать, чтобы избежать проблем.
Какие данные передаватьК сожалению, полный интероп между Kotlin и Swift если и возможен, то не сегодня: текущие проблемы и ограничения хорошо систематизированы в Kotlin-Swift Interopedia. JetBrains делает очень много по развитию Swift Export, прямого экспорта в Swift без Objective-C-прослойки, но он всё ещё в Alpha, несмотря на значительные успехи за прошлые годы. Значит, мы должны подумать о том, как не усложнить жизнь iOS-разработчикам.
Наши UseCase'ы будут возвращать только Domain Entities, в обёртке DomainResult, или Flow из них. Так мы будем уверены, что объекты на той стороне поведут себя ожидаемо, потому что интероп примитивных типов работает отлично. Например, даже привычные sealed-классы Kotlin не заработают в iOS «из коробки» так, как в Android.
Событие, по словам экспертов, усилит конкуренцию в сфере ИИ.



