Мой бекграунд это 10 лет мобильной разработки, в большей степени это Android разработка, но есть опыт разработки iOS приложений, в том числе Swift UI. Что же поехали, ниже пошаговый гайд и проблемы, которые я встретил.
Шаг 0. Определяем концепцию и составляем план работ
Шаг 1. Подготовительные работы. Генерация проекта и создание репозитория
1.1. Создаем репозиторий в Github
Создаем репозиторий для проекта. Для open source добавляем лицензию и README.
Код шага:
1.2. Через студию генерируем стандартный проект
Генеруем проект, делаем первую сборку и запускаем под разные платформы. Если все работает, круто, идем дальше.
Код шага:
1.3. Формируем стек технологий
Собрал базовый и современный стек технологий. В прещениационном слое решил использовать свою библиотоеку, построенную на принципах udf и паттерне mvvm.
Шаг 2. Читаем и изучаем KMM
Оф дока от Android.
Оф дока от Kotlin.
Карта погружения
Шаг 3. Собираем core часть проекта
3.1. Объязательно актуализируйте зависимости
Пригодится
3.2. Add logger with Naiper
Забавные моменты:
Первый момент, нельзя сгенерить модуль будучи в подпапке или подмодуле через интерфейс AS, только через root проект рядом с app.
Второй момент, если у нас commonJvm only модуль, не подтянивает соурсы кода, для того чтобы заработало нужно ставить заглушку в виде jvm таргета.
Третий момент, важно если это непубличная либа, то убирайте androidLibrary, генерится по умолчанию. Добавьте просто android.
Четвертый момент, долго не мог разобрать как использовать стандартный api/impl подход. Получилось так:
- обязательно делаем в апи модуле все таргеты, для доступа в платформенной коде к интерфейсу
- Далее актвируем "kotlin.experimental.expectActualClasses=true"
- В commonMain модуле фиксируем expect impl
- В платфомренном коде реализуем через actual impl класс
Пятый момент, чтобы сделать вызовы в ios приложении иницинализаторы, например logger смотрите в shared модуле название модуля, например ComposeApp. Делаем в иос коде import и используем методы в коде иос.
Шестой момент. Расширение .kt в iosMain невсегда отображается, баг.
Инструкция:
Итог шага:
3.3. Add local storage with Data Store KMP
Не забываем про ограничение в один экземпляр, для этого реализуем signlton подход с синхронизацией. Для iosMain можете использовать kotlinx.atomicfu.
Подробнее про использование kotlinx.atomicfu:
Data Store:
Итог шага:
3.4. Делаем абстракцию над coroutines для unit тестов
Итог шага:
3.5. Добавляем базу данных с Room
Все как в андройд, больших отличий не заметил.
Итог шага:
3.6. Добавляем di на базе koin
Koin имеет максимально большую поддержку в коммюнити, также сделан под разные платформы, в том числе бекенд и активно развивается, поэтому выбор пал на него. Dagger варианты с compile check, к сожалению, не имеют таких стабильных релизов, поддержку со стороны коммюнити и распростарнение в разных сферах, например бекенд и тд.
Официальный гайд:
Итог шага:
3.7. Добавляем навигацию Navigation 3
Документация:
Поможет вам:
Итог шага:
3.8. Добавляем презентационный слой
В общем и в целом, можно использовать mvvm или mvi паттерн с поддержкой KMP.
Я решил написать свой фреймворк на основе MVVM.
Итог шага:
3.9. Добавляем build-logic
Делаем общую билд логику, чтобы снизить боллерплейт кода в файлах конфигурации build.gradle.
Я решил написать свои Gradle плагины и опубликовал их.
Итог шага:
В процессе переноса в отдельную репу:
#технологии #it #dev #Android #AndroidРазработка #Kotlin #Java #OpenSource #РазработкаПриложений #MobileDevelopment #Разработка #Приложения
#KMP #KotlinMultiplatform #Мультиплатформа