Сейчас существует широкий спектр кроссплатформенных технологий, среди которых Flutter, React Native и, конечно же, Kotlin Multiplatform Mobile (KMP). Какую технологию стоит выбрать и почему именно ее? Давайте попробуем разобраться!

Все технологии имеют свои преимущества и недостатки, но ни одна из них не решает всех проблем. Проще говоря, ваш выбор будет зависеть от конкретных задач.
Ребята из JetBrains проделали невероятную работу для оптимизации затрат на разработку и переиспользование кода. Причем повторное использование возможно не только внутри одной платформы, но и между разными платформами (Android и iOS). Если ваша команда разработчиков хочет сохранить нативный UI для каждой платформы, то Kotlin Multiplatform Mobile — идеальный вариант.
Это связано с тем, что Kotlin Multiplatform вообще не поддерживает пользовательский интерфейс. Вместо этого она позволяет реализовывать бизнес-логику для приложений на Android и iOS. Из-за особой конфигурации можно создать проект, который будет скомпилирован в библиотеке Android с конкретным кодом для Android, а во фреймворке iOS — с соответствующим кодом для iOS. С технической точки зрения больше нет проблем с одновременным использованием одного и того же кода на iOS и Android. Когда вы отлаживаете свой код, вам нужно отредактировать его только один раз, а изменения произойдут на обеих платформах. Однако на нативной стороне приложения не стоит выносить в общий код:
весь интерфейс;
привязку интерфейса к общей ViewModel из общей библиотеки кода;
особенности платформ: работу с камерой, NFC, Touch ID или Bluetooth.

И в любом случае общий UI между платформами не является необходимостью. При обобщении UI требуется несколько итераций, чтобы сделать его и поведение приложения более нативными. Что, разумеется, требует дополнительных циклов разработки.
Flutter использует canvas из нативного SDK для разных платформ и рисует свои UI-компоненты на нем с помощью Material Design specifications. React Native использует собственные компоненты в JS-коде. React дает возможность обновлять логику приложения без повторной сборки проекта и загрузки в стор (JS-код загружается с серверов и сразу начинает работать на устройстве, без обновления всего приложения).
Что касается бизнес-логики, она является общей для Flutter и React Native. Соответственно, она пишется на языках Dart и JavaScript, с которыми мобильные разработчики, привыкшие к нативному стеку, не знакомы. Для этих платформ потребуется прослойка между нативным и ненативным кодом.

Согласованность дизайна для всех версий операционной системы и между операционными системами является еще одним преимуществом Flutter. Эта технология также позволяет легко создавать кастомный дизайн. Сравнивать высокую скорость разработки и высокую производительность Flutter с другими технологиями вряд ли есть смысл, так как это однозначно его фишка.
В Kotlin Multiplatform Mobile нет промежуточных слоев, что практически устраняет любые узкие места при взаимодействии. А поскольку Kotlin Multiplatform работает с нативными экосистемами каждой платформы, разработчики могут использовать инструменты и библиотеки, которые они всегда использовали, включая Swift UI и Jetpack Compose. Любые ограничения, с которыми вы сталкиваетесь, всегда можно обойти с помощью Kotlin, Swift или любого другого языка, который удобен для решения конкретных проблем с наименьшим риском. Но в случае с Flutter вы должны оставаться верным только Dart, а с React Native — только JS.

Kotlin Multiplatform не требует использования VM, в отличие от React Native. Несмотря на то что Flutter также не требует VM в разработке, вы должны писать на ненативном языке в ненативной экосистеме. В то же время в Kotlin Multiplatform очень легко писать собственный код на любом уровне абстракции и на любом уровне архитектуры.
В отличие от Flutter или React Native, где вы должны продолжать работу с их инфраструктурой, KMM может интегрироваться в любой существующий проект. Внедрение KMM может осуществляться поэтапно, без необходимости останавливать текущий процесс разработки. Мы готовим roadmap по расширению использования KMM в проекте, чтобы после каждого шага можно было выполнять релиз в стор. Также важно, что мы расширяем использование KMM с текущим кодом приложения, что помогает спасти проект от новых багов.

В KMM-проекте требуется только один специалист для создания общего кода и нативной части своей платформы. Специалиста другой платформы потребуется подключить только для внедрения пользовательского интерфейса в существующую логику. Код пишется только один раз, что исключает риск появления двух багов вместо одного.
В результате поддержка и разработка приложения становятся намного дешевле, эффективнее, реализация функций также будет заметно быстрее, и в то же время вы сохраняете полную нативность как для разработчика, так и для пользователя.
Комментарии (21)

Tuwogaka
18.01.2022 12:51+2И что же я вижу в этой попытке убедить меня что КММ есть источник радости, счастья и богатств?
"Kotlin Multiplatform Mobile (KMP)" - Буковки разве совпадают? И сам факт параллельного существования КМР и КММ при взгляде на технологию со стороны как минимум весьма настораживает.
"рисует свои UI-компоненты на нем с помощью Material Design specifications" - заимствование качества логики у либеральных экономистов? Вера в самореализацию любых псевдопринятых норм? Всегда считал, что Flutter рисует своё с помощью Skia, которая находится в непонятных мне отношениях с SDL которая покрывает Skia как бык овцу.
"В KMM-проекте требуется только один специалист для создания общего кода и нативной части своей платформы." - Какой такой "своей"? Писали бы честно - может переиспользоваться специалист (?) по Андроид.
И чего я не вижу? Смысла. Смысла зачем всё это нужно JetBrains, особенно на фоне Fleet. Зачем Flutter заворачивать С++ в Dart. Что вдруг побудило всех выдавать альфу за бету, бету за релиз и подавать себя как (почти) полностью кросплатформенное решение? Стоит ли на этом фоне продолжать погонять (мертвую маркетинговую) лошадь бизнес-логики?
Просьба любителей комментировать заметив знакомую букву заметить, что текст выше не про перечисленные вопросы. И непро ответы на них. Он про качество статьи.

maria-93
18.01.2022 15:33Интересно, сколько времени в среднем занимает "вкатывание" нативного разработчика в KMM (из вашего опыта?)

IceRockDev Автор
18.01.2022 15:34Из нашего опыта, чтобы освоиться в проекте и в этих технологиях, андроид-программисту надо не больше 1-2 недель, айоснику - больше, может быть месяц, но всё сильно зависит от опыта и настроя специалиста :)

wardrone
18.01.2022 17:23+4Добрый день. Спасибо за статью. Хотелось бы добавить несколько уточнений, т к имею опыт работы в мобилках как в нативке (приложения под android, ios) так и в кроссплатформе (cocos2dx, unity3d, flutter)
-
"Это связано с тем, что Kotlin Multiplatform вообще не поддерживает пользовательский интерфейс. Вместо этого она позволяет реализовывать бизнес-логику для приложений на Android и iOS."
- Еще задолго до КММ для этого подходили C/C++ (c JNI мостиком на стороне android, зато с замечательной совместимостью на ios). На самом деле тут можно привести много примеров, компилируемых языков, которые мы можем использовать.
-
"Для этих платформ потребуется прослойка между нативным и ненативным кодом."
- Но ведь и для связи Kotlin и Swift нужно писать интерфейсы. На мой взгляд, это такая-же прослойка, как и каналы в Flutter
-
"И в любом случае общий UI между платформами не является необходимостью. При обобщении UI требуется несколько итераций, чтобы сделать его и поведение приложения более нативными. Что, разумеется, требует дополнительных циклов разработки."
- Действительно, качественный универсальный UX требует хороших специалистов (как дизайнеров, так и разработчиков). Но вот про дополнительные циклы разработки не соглашусь. Общий UI не является необходимостью, но это одна из точек экономии затрат на проекте именно из-за уменьшения циклов разработки/тестировния.
-
"А поскольку Kotlin Multiplatform работает с нативными экосистемами каждой платформы, разработчики могут использовать инструменты и библиотеки, которые они всегда использовали"
- Ребята, при желании это можно и к Flutter присоединить. Только вот незачем. Не кажется ли вам что просто мы все заждались Compouse for IOS (но тогда надо упомянуть что он так же на Skia)?
-
"Любые ограничения, с которыми вы сталкиваетесь, всегда можно обойти с помощью Kotlin, Swift или любого другого языка, который удобен для решения конкретных проблем с наименьшим риском. Но в случае с Flutter вы должны оставаться верным только Dart, а с React Native — только JS."
- Повторюсь, flutter взаимодействует с нативкой через каналы. И это очень просто, ну правда. К тому же, если команда созрела на кроссплатформу то придется опускаться и в kotlin и в swift. Без этого никак.
"Вы должны писать на ненативном языке в ненативной экосистеме. В то же время в Kotlin Multiplatform очень легко писать собственный код на любом уровне абстракции и на любом уровне архитектуры"
- Разработка под KMM != Разработке под Android и уж совсем далека от разработки под iOS, везде свои особенности, библиотеки и инструменты, которые придется изучать
-

Aprsta
18.01.2022 19:26С Kotlin multiplatform теперь можно писать и общий UI при помощи Compose и Skiko, хоть для Web, Android, Desktop, Ios. Единственое что несколько compose библиотек типа material3 и ui-tooling еще не работают, но я думаю потом их тоже можно будет использовать в общем коде.

mrTyler
18.01.2022 23:51Итого получается, я, как разработчик, могу взять Flutter или React Native и написать 1 приложение для двух платформ (оговорюсь, что минимальные знания Java и ObjC все же потребуются), скомпилировать его и отправить в сторы, а вот чтобы написать на KMM, мне потребуется написать бизнес логику, потом написать UI для каждой платформы, которую я хочу поддерживать.
1 раз написал - используешь везде в случае KMM работает на пол шишечки, простите.
Aprsta
19.01.2022 01:38+1Это не так, для KMM есть UI на Compose и Skia и он работает на всех платформах: linux, windows, android, ios, macos, web
Вот тут есть проект где показывается как это работает: https://github.com/JetBrains/compose-jb/blob/master/examples/falling-balls-mpp

fuliozor
19.01.2022 11:20+2Не вводите людей в заблуждение, на данный момент Compose не умеет работать с iOS, если перейти в корень репозитория, который вы привезли в пример, то там во втором же абзаце написано
Compose Kotlin UI framework port for desktop platforms (macOS, Linux, Windows) and WebНа данный момент отсутствие кросплатформенного UI самый большой минус.

Aprsta
19.01.2022 13:56-1Сам пример falling-balls-mpp появлся 9 дней назад, а альфа compose 1.1.0, с которой стало вообще возможно делать ui на ios и web через skiko, появилась немногим раньше. Поэтому я уверен что описание в родительском проекте compose-jb, про которое вы говорите, еще не поправили (или поправят, когда 1.1.0 выйдет в релиз).
В основном build.gradle.kts увидим таргеты под ios:
https://github.com/JetBrains/compose-jb/blob/master/examples/falling-balls-mpp/build.gradle.kts
А вот весь код Ios в одном файле просто вызывает composable:

denis_gap
19.01.2022 05:38Да, но при этом в KMM ты остаёшься с возможностью натива. Может нам не нужно унифицировать ui или мы хотим платформенно-специфичные фичи реальзовать тоже на нативе.

mrTyler
19.01.2022 08:45+1React Native также позволяет реализовывать нативные решения и интегрировать их в проект, это не преимущество KMM.
Если уж по чесноку, то в преимущество KMM я бы записал возможность реализовать бизнес логику 1 раз в SDK и поставлять этот SDK под разные платформы, вот тут кроется самый его большой плюс, но опять же у нас есть C++, он тоже дает такую возможность.
Сейчас я вижу, что KMM могут себе позволить только большие команды, проекты на старте скорее всего погибнут в веренице интеграций и количестве участников в проекте, в то время, как маркетплэйс может реализовать на Flutter 1 человек для двух платформ.

Mitai
19.01.2022 12:52+1Всем давно понятно что флаттер покорил кроссплатформу

ogregor
19.01.2022 13:17Не соглашусь, ещё не совсем, а вот React Native да. Для флаттер до сих пор ещё много что не сделано. К примеру популярные библиотеки для работы с криптовалютами и криптокошельками. Я бы сейчас тысячу раз подумал над тем, стоит ли делать ethereum совместимый кориптокошелек на flutter. Насколько сильно это удорожит разработку по сравнению с JS и RN?

Mitai
20.01.2022 11:03не понял как криптовалюта связанна с инструментом для отрисовки UI? Flutter должен рисовать то что сотворил ваш дизайнер и с этим он справляется, работа с криптокошельками на мой недо джуновский взгляд все таки уже работа бека нет?

ogregor
19.01.2022 13:23По мне так идеального инструмента ещё не придумали. А идеальный инструмент это flutter на JavaScript - TypeScript. JS -Прежде всего потому что позволяет тысячам фронтендеров лёгко разрабатывать под кроссплатформу, без необходимости вникать в другие языки и технологии, в большинстве случаев.
Dart по сути своей это тот же JS - TS, только им пришлось поменять синтаксис, так как TS это Майкрософт. Под капотом у него аналог V8

Mitai
20.01.2022 11:09ну если мы тут о мечтах, то лучше уж тогда раст, туда засунуть, но уж ни как не JavaScript или его якобы типизированную надстройку, та же какашка только в блестящий золотинке...

Atreides07
20.01.2022 00:13+1"В KMM-проекте требуется только один специалист для создания общего кода и нативной части своей платформы. Специалиста другой платформы потребуется подключить только для внедрения пользовательского интерфейса в существующую логику. Код пишется только один раз, что исключает риск появления двух багов вместо одного.
В результате поддержка и разработка приложения становятся намного дешевле, эффективнее, реализация функций также будет заметно быстрее, и в то же время вы сохраняете полную нативность как для разработчика, так и для пользователя."
Flutter требует двух спецов на старте? Или в Flutter требует ждать пока все перекомпилируется как в KMM? Или это Flutter страдает от Gradle который регулярно ломает KMM чуть ли не при каждом апдейте? Серьезно, где логика? Назовите хоть одно место где KMM дешевле, эффективнее и быстрее реализация?
KMM потенциально отличный проект, и всем очевидно что у KMM будет огромное преимущество после появления Compose для iOS, но вот слепая необъективная фанатичность различных Android блогеров и авторов и неприкрытая манипуляция словами граничащая с откровенным враньем в попытке преуменьшить недостатки и/или преувеличить достоинства KMM просто поражает. Это результат каких то комплексов по поводу Flutter или что-то другое?
denmusic1992
Интересная статья. А начинающему разработчику, который не знает еще языка Kotlin, не легче ли ему изучить Dart и начать разработку на Flutter? Какие могут быть там подводные камни?
IceRockDev Автор
Вход в программирование на Flutter действительно ниже, благодаря материалам от Google, можно собрать своё простенькое приложение довольно быстро, но это не избавит вас от знания мобильных операционных систем и от специфики мобильных платформ, это всё равно нужно знать при создании мобильных приложений.
ynlvko
Иногда складывается ощущение, что сторонники Kotlin начали чувствовать давление со стороны Flutter, и из-за этого начинают топить за любимый стек. Синдром утёнка?
В статье есть несколько неточностей, но на них указали в комментариях ниже.
Насчёт специфики мобильных платформ - я скорее не соглашусь, чем соглашусь. Да, команда из Android и iOS разработчиков идеальна, но это совершенно необязательно.
Я как-то фрилансил, и был проект, в котором были сканирование QR-кодов камерой, работа с Bluetooth (соединение с аппаратным сканером QR-кодов и RFID меток), работа с сетью, локальное хранение данных. Изначально клиент хотел только Android-приложение, но я решил сделать всё на Flutter, для практики. Тестировал только Android. Когда я сдавал проект, клиент захотел и iOS, и как удачно это всё было на Flutter'е, я просто сделал сборку iOS (предварительно настроив используемые библиотеки для платформы, это заняло до 30 минут) и отправил клиенту.
Знание специфики работы платформы необходимо только при разработке своей кросс-платформенной библиотеки, тесно работающей с платформой, что требуется не так уж и часто.
А Hot Reload вообще перевернул с ног на голову. Так больно ждать сборку Android-проекта даже 1 минуту (а некоторые проекты собираются значительно дольше) после незначительных изменений, когда можно нажать "Сохранить" и наблюдать изменения спустя секунду.