Комментарии 29
А iOS, соответственно, берет просто бизнес-логику Shared целиком и у себя уже имплементирует UI.
...
Затаскивание новых файлов в iOS-проект — отдельная боль
Есть замечательный плагин SKIE, который помимо кучи разных плюшек позволяет бандлить Swift код, находящийся в кмп модулях. Таким образом можно достичь true многомодульности и хранить iOS ui в кмп модулях.
Использование Kotlin Multiplatform в разработке оказалось не таким болезненным, как может показаться на первый взгляд.
Довольно своеобразная реклама, я бы сказал 🙂 Не сказать, чтобы пробуждала непреодолимое желание попробовать.
Пара вопросов:
Главное: а чем, собственно, был обусловлен выбор именно КМР? В мультиплатформе сейчас есть флаттер, RN (не к ночи будь помянут), кордова всяческая. Почему КМР – опыт с Котлином был?
Эти метрики по размерам 60М+ к чему относятся – сборка голой базы приложения, без функционала?
Я таки на КМР не рискнул – сыроватым показался. Правда, это было больше 2х лет назад. С реактом мы в своё время нахлебались, желание продолжать пропало. Кордова тоже не впечатлила, так что взяли флаттер. Если бы пришлось сейчас писать статью – она явно была бы более позитивной, чем эта. Небольшие заморочки есть, но плюсов намного больше. И размер, кстати, сильно меньше 🙂 Аппа с десятками экранов сейчас 37М. Три платформы - Android, iOS, web, platform-specific кода почти нет – для веба по большей части. Десктоп теоретически тоже можно, но не пробовали – нет необходимости.
Я таки на КМР не рискнул – сыроватым показался
Так он и сейчас сыроватый, в этом и проблема. А так сам язык Kotlin раз в 5 более развит, чем Dart. Хотя в Dart есть свои плюшки, как то const-классы из коробки с возможностью оптимизаций (хотя вроде в Kotlin в виде надстройки что-то подобное добавили).
А так сам язык Kotlin раз в 5 более развит, чем Dart.
Ну в пять – это перебор, наверное 🙂 Чего же в том котлине есть такого волшебного? На сегодняшний день дарту, пожалуй, не хватает одного: позднего статического связывания. Причём похоже, оно и не планируется, увы. А в остальном всё нужное для эффективного программирования есть. Жаль, что от макросов/метапрограммирования они отказались в конечном итоге – но это совсем не смертельно. В целом на нём пишется комфортно.
А КМР да – сколько ни смотрел, он всё в бете: "ждите, почти готов, вот-вот будет".
Если совсем коротко, то Котлин это первый вариант бесшовногно интеропа с нативными языками. Все остальное - фреймворки.
Второй важный аспект - нативная скорость и качество андроида.
Котлин это первый вариант бесшовногно интеропа с нативными языками
Не очень понял. Дарт точно так же бесшовно компилится в натив, причём на большем количестве платформ. А КМР/СМР точно такие же фреймворки, как и флаттер.
Со скоростью тоже всё в порядке.
Вопрос не в компиляции, а в бесшовном вызове из нативного кода.
И котлин в этом плане не фреймворк, можно буквально из нативного кода создать просто экземпляр одного класса (модель) из нативного кода - и все будет работать так, как будто ты используешь айосную библиотеку
практически - это невозможно использовать в готовых приложениях
Звучит загадочно. Почему? И где тогда можно?
Ну, 1-2 раза ты можешь в коде такое накодить и даже считать, что контроллируешь процесс.
Я скорее про случай, когда у тебя есть готовое приложение и тебе из него готового надо дергать флаттер кусочками.
Таким образом мы получаем ситуацию, когда мы получаем абсолютно не дебажную историю с абстрактным асинхронным вызовом чего-то.
Котлин в этом плане синхронен и платформенен - он просто в objC компилится.
Я скорее про случай, когда у тебя есть готовое приложение и тебе из него готового надо дергать флаттер кусочками.
Этого совсем не понял. Пишем новое приложение, прямо на флаттере, где надо, вставляем ffi
. Повторюсь – если надо. Можно пример, где это вообще необходимо? Вот реально ни разу не понадобилось, всё решается средствами языка/фреймворка.
Котлин в этом плане синхронен и платформенен - он просто в objC компилится.
И дарт ровно то же делает, компилится в нативный код платформы. Флаттер как таковой тут вообще ни при чём, ffi
– фича языка, а не фреймворка. Библиотека dart:ffi
Для понимания – я не пытаюсь тут доказать, что флаттер чем-то лучше котлина, мне реально интересно.
Котлин в этом плане синхронен и платформенен - он просто в objC компилится.
Как бы перевернули зависимости, по сути. Flutter пошел по классике - он конечное звено, если нужны нейтивные либы - то для каждой пишем нейтивную обертку и дергаем через FlutterMethodChannel, включая события из нейтивной.
KMP пошли по другому пути - конечное звено нейтивное приложение и оно дергает либу на KMP.
Интересно изменит ли концепцию Compose Multiplatform?
Так и в дарте так можно.
Это другое. С помощью ffi вы можете вызывать программы на голом C (или на любом другом ЯП, но сузив его до возможностей языка С) - из Flutter.
А чел. говорит об обратном - он пишет класс на Kotlin Multiplatform и потом дергает этот класс из Android-Kotlin или iOS-Swift-кода.
Причем все делается очень прозрачно, как будто класс нейтивный для той платформы.
Но не знаю удобно ли это, фактически вам нужно знать два языка.
Flutter не притворяется как будто он часть экосистемы для iOS - там явно дергаете через FlutterMethodChannel.
Kotlin Multiplatform - как бы перевернули зависимости - теперь нейтивные приложения разных платформ зависят от библиотек KMP. А Flutter классически - он конечное звено и юзает (зависит) от нейтивных библиотек разных платформ, а уже эти библиотеки, если им нужно что-то вызывать из Flutter-связующего звена - дергают через не прозрачный FlutterMethodChannel.
А чел. говорит об обратном - он пишет класс на Kotlin Multiplatform и потом дергает этот класс из Android-Kotlin или iOS-Swift-кода.
Ух. Тогда точно у меня главный вопрос – зачем. Есть нативные аппы для Х платформ, и чтобы расширить их функционал, пишется некий общий модуль на КМР, а потом в них вкорячивается? Звучит крайне экзотично, мне такое и в голову не приходило. Тут ведь не просто
фактически вам нужно знать два языка
Нужно знать Х+1 – ибо вероятно, команды, разрабатывавшие натив тоже никуда не делись. И теперь каждой из них нужно осваивать интеграцию с КМР. А если понадобится внести мелкое изменение в нативный код – что делаем? Переписываем на КМР, потому что политика партии поменялась? В нативе это может быть фикс на пару минут, а переписывание занять недели, если не месяцы. С Андроидом вообще какой-то бред получается – часть кода на чистом Котлине (который там и так вполне родной), часть под зонтиком КМР. Ну или Андроид реализация отличается от всех остальных.
А как СМР ко всему этому пристёгивается? Добавляется к нативным библиотекам? Какое-то месиво получается, никогда бы не пошёл на такое. Ради чего? Ну или я по-прежнему чего-то не понимаю.
Кстати, формально флаттер тоже умеет работать в обе стороны. Но да, это не будет выглядеть, как вызов родного класса/метода – ни в одном направлении. Только с JS можно делать нечто похожее.
Кстати, формально флаттер тоже умеет работать в обе стороны.
Ну да, именно так и делаются библиотеки для Flutter, с адаптером на каждой нейтивной платформе. К примеру, вот эта:
Из Kotlin дергаете методы Flutter по событию через io.flutter.embedding.engine.FlutterEngine
Из Swift дергаете через реализацию FlutterPlugin.
А на Flutter генерите байндинги.
Только это все как бы более сложно, возможно подход Kotlin более продвинутый, как бы переработка концепции. Время покажет.
Только это все как бы более сложно, возможно подход Kotlin более продвинутый, как бы переработка концепции.
Да честно говоря, мне кажется, что оба в принципе об одном и том же – если их использовать, как изначально задумано.
Котлин появился (и стал популярным), как альтернатива джаве – но в какой-то момент они решили отвязаться от JVM и запилили кучу компиляторов под разные платформы – aka KMP.
Дарт задумывался, как альтернатива JS, но в этом качестве не взлетел – и тогда они решили сделать его универсальным, и опять же напилили кучу компиляторов.
Но поскольку оба – универсальные языки, ничего не знающие о том, где будут запускаться, им понадобилась адаптация к средствам отображения целевых платформ. У котлина это СМР, у дарта – флаттер. Собственно, всё. Дальше вопрос в значительной степени вкусовщины, а возможности там и там примерно те же. Наверное, КМР (по уже обсуждавшимся причинам) несколько ближе к железу, чем дарт – но зато флаттер предлагает побольше, чем чисто гуёвый СМР.
Так что если опустить странные сценарии типа прикручивания мультиплатформенных модулей к уже готовым нативным приложениям, то выбор не совсем очевиден – собственно, поэтому я и влез в тему, было интересно, что движет теми, кто выбрал КМР.
Да честно говоря, мне кажется, что оба в принципе об одном и том же – если их использовать, как изначально задумано.
Dart-класс вызвать из Android+Kotlin или iOS+Swift - это целая история с обертками - пусть даже и генерятся они полу-автоматизированно (Pigeon).
А KMP - смогли это все скрыть под капотом, что очевидно более продвинутый подход.
но зато флаттер предлагает побольше, чем чисто гуёвый СМР
Тут согласен, Flutter сейчас вне конкуренции для реальных нужд - уйма пакетов на все случаи жизни. KMP больше вклад в светлое будущее, а наступит ли оно...
Во всех подобных решениях до этого (что xamarin, что flatter, что react native) всегда было две беды - по этому про них интересно.
1 - это протекание абстракций - когда у тебя на серьезном проекте обнаруживается бага, протекшая в нативный код, так еще и на одной платформе, и ты неделями её дебажишь - тут такого не встречали? Лог ошибок всегда понятен и место их возникновения?
2 - когда на разных платформах есть разные возможности - то в суммарной версии нет никаких. Если нам надо работать с фоновыми задачами (при свернутом приложении), планировать отложенную активность, показывать нотифткации - надо будет все равно съезжать к нативному для платформы коду? И насколько болезненно взаимодействие на ios между котлин и swift?
Без примера непонятно). Глобально нет, таких проблем нет. Бойлерплейта многовато, да, а так вроде все в порядке
В том то и соль, что котлин не ограничивает использование нативных фич и легко встраивается в нативный код. Мы виджеты поднимали для главного экрана, все с пол пинка заводится.
когда у тебя на серьезном проекте обнаруживается бага, протекшая в нативный код, так еще и на одной платформе, и ты неделями её дебажишь
Такого, чтобы вылезал баг, обнаруживаемый "в лабораторных условиях", который можно самому отдебажить – не припомню. Случаются странные баги, которые проявляются у очень малого подмножества юзеров и вылезают только на проде. Вот, например. Но это может случиться с любой внешней либой, вплоть до clib. А так качество тестирования у них неплохое, с чем-то действительно критическим пока сталкиваться не приходилось. За флаттер говорю в данном случае.
когда на разных платформах есть разные возможности - то в суммарной версии нет никаких
С таким тоже не встречались. Пока единственное значимое ограничение, связанное именно с платформой – отсутствие поддержки сервис воркеров в вебките. Поэтому на iOS web приходится тупо запрещать пуш нотифы. Но это косяк эппл, не флаттера. В остальном всё одинаково.
Постоянная, но легкая боль, так как превью в CMP + Android Studio не работает
В Android Studio 2024.3.2 Canary 5 наконец-то починили Preview
Спасибо за статью и пошаговые замеры.
Используется ли такой сетап в проде приложений Яндекс 360 и насколько широко?
Заезжаем в Kotlin Multiplatform. Но какой ценой?