> Насколько интересно писать на Kotlin Multiplatform и участвовать в переписывании Android и iOS приложений (Kotlin, iOS, Swift, Android)

Уровень: senior · Роль: mobile · Категория: Технические вопросы

Компании: Travelata

Стек: Kotlin, iOS, Swift, Android

> Пример ответа

Короткий ответ

Kotlin Multiplatform интересен как инженерный вызов: вы получаете единую бизнес-логику на Kotlin, но сохраняете нативные UI и платформенные API. Это снижает дублирование кода, но добавляет сложности с expect/actual, синхронизацией версий и тулингом. Участие в переписывании - это возможность переосмыслить архитектуру, но нужно быть готовым к trade-off между скоростью разработки и нативной гибкостью. Интересно, если вам нравится решать задачи на стыке платформ.

Подробное объяснение

Kotlin Multiplatform (KMP) - это не про "один код на всё", а про шаринг логики: сетевой слой, репозитории, state management, валидация, декодирование JSON. UI остаётся нативным - SwiftUI/UIKit для iOS и Compose/Views для Android. Это принципиально отличает KMP от Flutter или React Native.

Интерес в KMP складывается из нескольких факторов:

  • Архитектурная свобода: вы сами решаете, что выносить в shared-модуль. Можно начать с малого - только сеть и модели - и постепенно расширять.
  • Работа с expect/actual: это механизм, который заставляет думать о платформенных различиях явно. Например, работа с файловой системой, датами, криптографией - всё это требует actual-реализаций.
  • Kotlin/Native и memory model: нужно понимать, как работает заморозка объектов, потоки, взаимодействие с Objective-C/Swift через generated framework. Это добавляет глубины.
  • Инструменты: Gradle, cocoapods, Xcode integration, klib, binary compatibility - всё это требует отдельного скилла.

Переписывание приложений на KMP - это отдельный сценарий. Обычно это означает:

  • рефакторинг существующей логики из Swift и Java/Kotlin в общий модуль;
  • необходимость сохранить поведение и API, но улучшить тестируемость;
  • часто переписывание сопровождается внедрением новых подходов: MVI, Clean Architecture, DI (Koin, Kodein).

Сложность в том, что iOS-часть на Swift и Android-часть на Kotlin могут иметь разную историю, разные модели данных и разный уровень качества. Приведение их к общему знаменателю - это долгий итеративный процесс.

На практике

На практике KMP интересен, когда:

  • у вас есть команда, которая готова учиться и поддерживать общий код;
  • продукт имеет сложную бизнес-логику, которая действительно дублируется;
  • вы готовы к тому, что часть времени уходит не на фичи, а на инфраструктуру: настройка сборки, интеграция с Xcode, отладка Kotlin/Native.

Типичный рабочий процесс:

  • shared-модуль содержит: модели, сетевой слой (Ktor), навигацию (частично), state (например, ViewModel на Kotlin), DI, логику.
  • Android-приложение использует shared-код напрямую, часто через Compose.
  • iOS-приложение подключает shared-фреймворк через Swift Package Manager или CocoaPods, и вызывает Kotlin-классы из Swift.

Проблемы, с которыми сталкиваются на практике:

  • Swift ↔ Kotlin mapping: не все типы маппятся удобно. Например, sealed class в Kotlin становится enum с associated values в Swift - это работает, но не всегда интуитивно.
  • Coroutines и Swift Concurrency: нужно аккуратно мостить suspend-функции и async/await. Есть поддержка, но есть нюансы с cancellation.
  • Производительность: Kotlin/Native не всегда так быстр, как нативный Swift, особенно в горячих путях.
  • Отладка: дебажить Kotlin-код из Xcode сложнее, чем из Android Studio.

Пример кода

Простой пример expect/actual для получения текущего времени в миллисекундах:

// shared/src/commonMain/kotlin/Platform.kt
expect fun currentTimeMillis(): Long

// shared/src/androidMain/kotlin/Platform.android.kt
actual fun currentTimeMillis(): Long = System.currentTimeMillis()

// shared/src/iosMain/kotlin/Platform.ios.kt
import platform.Foundation.NSDate
import platform.Foundation.timeIntervalSince1970

actual fun currentTimeMillis(): Long =
    (NSDate().timeIntervalSince1970 * 1000).toLong()

Пример вызова из Swift:

SWIFT
let time = PlatformKt.currentTimeMillis()

Как отвечать на собеседовании

На собеседовании важно показать, что вы понимаете не только плюсы, но и ограничения KMP. Отвечайте структурно:

  • начните с того, что KMP - это не замена нативному UI, а шаринг логики;
  • приведите конкретный пример, что вы выносили в shared-модуль и почему;
  • расскажите про expect/actual и как вы решали платформенные расхождения;
  • упомяните инструменты: Gradle, CocoaPods, Xcode, Kotlin/Native;
  • покажите, что понимаете trade-off: скорость разработки против сложности инфраструктуры.

Если вас спрашивают про переписывание - говорите о стратегии: как вы анализировали существующий код, что оставили на платформах, как обеспечивали совместимость с существующими фичами.

Что проверяет интервьюер

Интервьюер оценивает:

  • понимание архитектуры KMP и места shared-кода;
  • знание Kotlin/Native, memory model, взаимодействия с Swift;
  • умение принимать решения: что выносить в общий код, а что оставить нативным;
  • опыт работы с инструментами и CI для мультиплатформенных проектов;
  • способность объяснить trade-off и риски.

Также проверяется, насколько вы реально работали с KMP, а не просто читали статьи. Вопросы про expect/actual, про сборку, про отладку - хороший фильтр.

Типичные ошибки

  • Утверждение, что KMP - это "один код на все платформы". Это не так, и это сразу выдаёт непонимание.
  • Игнорирование платформенных особенностей. Например, попытка вынести UI в shared - это антипаттерн, если только вы не используете Compose Multiplatform, но это отдельная история.
  • Непонимание memory model. Заморозка объектов, потоки, контексты - без этого нельзя писать стабильный код.
  • Отсутствие стратегии миграции. Если вы переписываете приложение, нельзя просто "взять и перенести всё". Нужен план: что переносим первым, как тестируем, как обеспечиваем обратную совместимость.
  • Недооценка сложности интеграции с iOS. Xcode, CocoaPods, Swift Package Manager, генерация фреймворка - это отдельная боль, и её нельзя игнорировать.
  • Отсутствие тестов. KMP даёт хорошие возможности для юнит-тестов на common-коде, но если вы их не пишете, то теряете главное преимущество.

> ГОТОВЫ К СЛЕДУЮЩЕМУ СОБЕСЕДОВАНИЮ?

Запустите тренировочную сессию с ИИ и получите детальную обратную связь, чтобы увереннее проходить реальные интервью