Kotlin Multiplatform
2.62K subscribers
84 photos
3 videos
407 links
Русскоязычный канал новостей о Kotlin Multiplatform
Download Telegram
А для тех кто уже успел ознакомиться со статьей от Badoo, есть интересная библиотека - реактивщину в kotlin multiplatform оказывается несут не только Badoo, но и Mirego. И их реализация зовется Trikot.streams. Эта библиотека так же позволяет делать реактивные цепочки с переключением потоков на обеих мобильных платформах (на native так же как Reaktive данные замораживаются для передачи между потоками), но от привычного Rx API библиотеки отличается.
Примеры использования trikot.streams выглядят очень похожими на LiveData, как в moko-mvvm, при чем так же есть конвертация stream в LiveData для android, а для iOS сделан дополнительный cocoapod с вспомогательными swift методами привязки stream к элементам на экране (как и в moko-mvvm).

#libs
Те кто ознакомился с проектом-примером от Karumi, который был в посте со статьей о тестировании, могли заметить что в gradle конфигурации общей библиотеки есть специальная gradle таска, которая генерирует на основе содержимого gradle.properties класс KotlinConfig, по аналогии BuildConfig в android. Эта функциональность далее была выделена в отдельный gradle-plugin который назвали Hagu. Благодаря ему можно вынести различную конфигурацию из кода в gradle.properties файл и иметь единое место для конфигурации. Но в отличие от android в mpp пока нет поддержки buildFlavor, поэтому для конфигурирования разных окружений (dev,prod,stage) это не особо подходит. Зато подходит для подключения разных buildSecret из переменных окружения CI в сборку (чтобы не хранить секреты в самом гите, особенно важно для опенсорс проектов).

#plugins
В одном из прошлых постов были разобраны возможные варианты по работе с датой и временем в common коде. Среди всех библиотек особо выделялась библиотека klock, так как имела практически весь нужный в мобильной разработке функционал. Сегодня хочется упомянуть другую библиотеку работы с датой/временем - fluid-time. Она так же поддерживает kotlin 1.3.50 и android (jvm), ios платформы. В ней есть работа с датами, временем, таймзонами, интеграция с kotlinx.serialization из коробки, timestamp. Но чего в ней нет, так это хорошей документации. Поэтому знакомиться с библиотекой и ее API надо через код.

Тем же кто решит заглянуть в gradle конфигурацию библиотеки для упрощения разбора следует сразу ознакомиться с gradle-plugin'ом, который был сделан автором библиотеки специально для поддержки всех своих библиотек.
Так же у автора есть fluid-stdlib - дополнения к kotlin-stdlib в котором есть вынесение в общий код Currency, Country (с использованием на платформах системных инструментов) и множество разных дополнений к типам данных. Опять же документация скудная, смотрите код.

#libs
Для тех кто пользуется REST API и имеет в проектах OpenAPI (Swagger) спецификацию (надеюсь проектов без серверной спецификации уже все таки нет) в проекте OpenAPIGenerator появилась поддержка генерации kotlin-multiplatform API. На днях вышел релиз, в котором данное изменение уже присутствует.
Генерируется api завязанное на ktor-client, coroutines, KotlinxSerializer (фича ktor-client). Наружу результат запроса выдается в виде HttpResponse из ktor, то есть снаружи можно без проблем обрабатывать любой статус-код.
Мы в IceRock пока не проверяли этот генератор, так как уже полгода пользуемся своим, который наконец-то выгрузили в опенсорс - moko-network. Он основан на более старой версии OpenAPIGenerator'а, но проверен уже несколькими боевыми проектами. Поддерживаются и сериализация enum'ов с разными имя-значение (что из коробки kotlinx.serialization не умеет, но в OpenAPIGenerator'е это реализовано аналогично как у нас), а так же сериализация делается не через фичу KotlinxSerializer чтобы напрямую каждому запросу указывать конкретный сериализатор, это избавляет от проблемы "только один list сериализатор на всю api". В ридми пока не заполнен блок использования, но можно посмотреть по проекту-примеру.
Те кто попробует официальную версию из OpenAPIGenerator'а - прошу напишите свой фидбек использования нам в чат (кнопка discuss). А если и с нашим плагином сравнить удастся - такой фидбек будет еще полезнее.

#plugins
Разработка приложений с общим кодом на обе платформы не нова, и среди популярных решений есть сейчас React Native (от которого некоторые большие компании начинают уходить), Flutter (к которому многие идут) и Kotlin Multiplatform (про который наш канал). И периодически слышен вопрос от некоторых разработчиков: вот на kotlin можно написать общую логику, но нельзя писать UI (точнее неудобно), а можно ли совместить общую логику на kotlin и общий UI на Flutter?
Ответ: да, можно. И это даже делали...На эту тему есть пара статей - Fast Prototypes with Flutter + Kotlin/Native (русский перевод) и Приложение для iOS и Android на Kotlin + Flutter UI. При чем у второй статьи есть и открытый код, а сама статья это пошаговая инструкция как сделать так же самому (первая же статья больше про сам принцип и немного про ограничения этого симбиоза).

Если задуматься над вопросом "а зачем?" то мысли есть такие:
1. Для разработки прототипа одним человеком (особенно если сделать автоматическую генерацию каналов для связи kotlin и flutter между собой) - нам нужен человек который и общую логику на kotlin напишет и ui сразу на обе платформы сделает, при чем с hot reload и действительно быстрой разработкой визуала;
2. Для дальнейшего развития этого прототипа в большое замудреное приложение, напичканное разными нативными штуками типа фоновых сервисов, интеграций разных экстеншенов и прочих платформенных штук. С заменой UI на нативный, привычный всем пользователям. То есть достигаем как можно быстрее состояния MVP для проверки гипотезы, а если ее ждет успех - тогда уже вкладываем ресурсы в нативную разработку (не выкидывая общую бизнеслогику написанную на kotlin).

Возможно и у вас есть свое мнение по поводу вопроса "зачем соединять flutter и kotlin mpp?" - заходите в чат и поделитесь.

#posts #cases
В очередной раз пост о Reaktive. Сегодня он особенный, так как библиотека получила первый релиз, а значит Rx в общем коде доступен и стабилен.
А в добавку к релизу у библиотеки появились новые дополнения:
1. интероп с rxjava2/3 - для тех кто постепенно переносит android приложение в общий код и имеет в самом приложении rxjava - будет проще цепляться к общему коду, который на Reaktive;
2. интероп с coroutines - тут уже не только с android миром, но и с другими multiplatform библиотеками можно взаимодействовать. Например сделать запросы через ktor-client с Reaktive, скрывая стандартные coroutines внутри.
Badoo одни из немногих в русском сегменте, кто развивает поддержку kotlin multiplatform в мобильной разработке. Спасибо ребятам :)

#libs
Уже пошла подготовка новой версии котлина к релизу - kotlin 1.3.60 EAP 1 уже доступен.
Общий список изменений большей частью содержит множество багфиксов, заметна большая работа над стабилизацией. В IDE улучшена поддержка gradle-kts (более быстрые подсказки, ура). Но самое интересное для мобильной мультиплатформенной разработки вынесено в отдельный список изменений (kotlin/native changelist) и тут видно сильно больше работы над развитием, чем стабилизацией:
* Добавлена поддержка Xcode 11 (это не означает что в kotlin 1.3.50 нельзя с xcode 11 работать, а значит что что все новые API выпущенные apple в Xcode 11 теперь доступны из kotlin);
* Добавлены новые таргеты - watchos, tvos, native android. Уже можно брать и пробовать шарить kotlin код по часам и андроида и айоса, по тв приставкам обеих платформ, и даже делать native библиотеки для андроида тоже на котлине, чтобы например достучаться напрямую до какой нибудь C библиотеки которую хочется подцепить в приложение;
* Улучшена производительность в некоторых кейсах (от 5 до 50 раз ускорения);
* Улучшена скорость сборки больших многомодульных проектов;
* Исправлена ошибка подсчета ссылок на стыке kotlin и swift при многопоточном выполнении;
* Исправлена ошибка приводящая к крешам на ios arm64.

Те кто пробуют поддержку новых таргетов - отпишите свое мнение в чат. А мы в скором времени поделимся своим фидбеком от работы с watchos из kotlin/native, там же в чате.

#news
На одном из наших проектов, который мы делали с использованием kotlin multiplatform, нам нужно было сделать вывод чисел с множеством знаков после запятой. Баланс кошелька криптовалюты и суммы перевода могут быть очень маленьким числом, но требовалась точность, так как каждый 0.000000001 это реальные деньги, при чем совсем не копейки. Как оказалось в kotlin common-stdlib нет bigdecimal, но обе мобильные платформы такой тип имеют, поэтому мы довольно быстро и просто сделали expect/actual класс BigDecimal, передав эту специфику на платформы...сейчас же никому не потребуется делать кастомный expect/actual, так как уже доступна библиотека kotlin-multiplatform-bignum (с поддержкой kotlin 1.3.50), которая содержит и bigdecimal и biginteger, и математические операторы.

#libs #cases
Со стороны общего кода становится доступно все больше возможностей по работе с специфичными мобильными функциями. Например, уже доступна библиотека blue-falcon, позволяющая работать с Bluetooth из общего кода - проводить сканирование устройств, подключаться к определенному и читать/записывать характеристики.
А в связке с moko-permissions, которая позволяет получать рантайм разрешения из общего кода, получается что даже при реализации, например, приложения-сканера устройств в общем коде будет совсем все, кроме UI.

#libs
В мобильной разработке на обеих платформах уже есть множество разных библиотек, предоставляющих основные компоненты для построения архитектуры приложения. Так как мобильные приложения в большинстве своем это просто клиентское приложение большей частью из UI, то речь идет про MV*. Сами подходы MVC, MVP, MVVM, MVI, VIPER, MVU и прочие не требуют использовать готовую реализацию, так как это просто подходы, но с готовой реализацей все же проще.
Несколько следующих постов будут посвящены обзору архитектурных библиотек в kotlin multiplatform.

Первая библиотека - moko-mvvm. Это порт классов LiveData и ViewModel из Android Architecture Components в мир kotlin multiplatform, поэтому для android разработчиков будет очень знакома. Причем для android ViewModel и LiveData остаются "настоящими" - из AAC, что позволяет использовать все нативные интеграции с тулингом и самими AAC. Для iOS был сделан свой вариант LiveData и ViewModel, но так как жизненный цикл экрана на iOS сильно проще чем на android - реализация тоже сильно проще.
Помимо простого портирования LiveData обзавелась множеством операторов, по примеру Rx, что позволяет построить любую логику реактивного преобразования данных.
Для iOS поставляется дополнительный cocoapod с методами привязки livedata к набору стандартных view, что упрощает интеграцию в iOS (а на android можно либо интегрироваться через DataBinding, либо например KotlinDataBind).
Так же предоставляется способ сообщения о одиночных событиях с ViewModel на UI - EventsDispatcher. Это не SingleLiveData, а система с конкретным интерфейсом слушателя, позволяющая компилятору проверить все ли из необходимых к реализации методов имплементировано на обеих платформах.

Проект пример доступен там же в репозитории.

#libs
Продолжим обзор архитектурных библиотек. Сегодня обратим внимание на библиотеку redux-kotlin. Это порт многим знакомого reduxjs в мир kotlin-multiplatform. Поддерживаются все платформы, доступные kotlin.
В архитектуре придерживаются 3х принципов:
* Единый источник правды (единый State);
* Состояние не изменяемое;
* Изменения в состояние могут быть сделаны только через чистые функции, создающие новое состояние.

Взаимодействие со стороны UI простое:
* подписываемся на изменение состояния (при каждом изменении применяем новый State к нашему UI так, как нам удобно);
* для выполнения действий пользователя, сообщаем хранилищу о действии через dispatch, который получает на вход одно из действий (заранее прописываемые классы).

При желании можно совместить redux с MVP/MVVM, используя ViewModel или Presenter для наблюдения за состоянием и передачи View нужных данных (все же изменения состояний берет на себя сам redux).

Наглядный пример можно посмотреть в презентации ReduxKotlin.org с DroidCon NYC 2019.

#libs
Следующая архитектурная библиотека - oolong. Она предоставляет компоненты для построения TEA (The Elm Architecture). Идея близкая к MVI и к redux. Есть Model, которая не изменяется ничем кроме функций в Update и есть View, в которую попадает итоговый результат изменения модели (новое состояние для рендера) - получаем MVU (такую аббривеатуру указывают авторы библиотеки).

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

Сама архитектура пришла из функционального языка Elm и про нее можно послушать неплохой доклад - The Elm Architecture (Алексей Пирогов).

Пример TODO приложения выглядит довольно внушительно, но по сути в этих 300 строках описана работа приложения заметок с фильтрацией, действиями над заметками и прочим (но без сохранения на сервер и сайдэффектов - все строго функционально).

Если кто-то уже использует или использовал такую архитектуру в приложениях для мобилок - расскажите про свой опыт в чат, пожалуйста.

#libs #videos
Еще одна архитектурная библиотека – kotlin-mobius. Это перенос mobius от spotify в мир kotlin multiplatform.

Сама архитектура mobius очень похожа на TEA, redux, MVI – есть модель, которая обновляется чистыми функциями, а функции эти запускаются вызовом событий. События вызываются от действий пользователя или же сайд-эффектами. Подход предполагает, что бизнес-логика будет как раз в чистых функциях и будет очень легко покрываться тестами. Подробнее про архитектуру можно послушать в выступлении Mobius: A Loopy UI Architecture - Ahmed Nawara, Spotify.

"Старший брат" в лице оригинального mobius от spotify получил довольно много внимания от community, что добавляет доверия.

Тем, кто захочет попробовать данную библиотеку потребуется сначала выпустить к ней апдейт на версии kotlin 1.3.50 (последняя версия библиотеки была собрана с 1.3.40). Хотя, если желающих будет достаточно, автор может отреагировать и на issue с просьбой обновления.

#libs #videos
Завершим серию постов об архитектурных библиотеках не библиотеками, а проектами. Компоненты под эти архитектуры не выделены в библиотеки, но в проектах-примерах можно посмотреть подход к реализации и сделать по примеру.

* MVP - jarroyoesp/KotlinMultiPlatform в общей логике находятся несколько Presenter'ов и их интерфейсы для View;
* MVP - sergiocasero/votlin-app;
* MVP - cmota/droidconLX;
* MVI - petrumo/KotlinMultiplatformMVI в общей логике и reducer'ы и state'ы и прочее, только применение стейта к UI в нативке. Плюс есть статья с разбором - Kotlin Multiplatform MVI.

#libs #posts
Тем, кто хотел увидеть Rx в общем коде в каком либо проекте, сегодня есть что почитать - статья Kotlin Multiplatform + Reactive подробно рассказывает о процессе создания небольшого приложения с использованием Reaktive, ktor, sqldelight на современной версии kotlin - 1.3.50. Приложение – простой просмотрщик списка фильмов с OMDb, с пагинацией и кешированием.

Что можно наглядно увидеть:
* Взаимодействие coroutines и Reaktive;
* Использование ViewModel'ей (подход, не библиотека);
* Использование UseCase;
* Применение подходов Clean Architecture в kotlin mpp;
* Не самый удобный подход интеграции kotlin-фреймворка в ios приложение (лучше все таки через cocoapods);
* Настройка и использование sqldelight базы данных в mpp.

Итоговый проект доступен на github.

#posts
Russel Wolf (автор одной из первых multiplatform библиотек – multiplatform-settings) недавно выступил с докладом о разработке приложения с kotlin mpp. В приложении сделано несколько общих gradle-модулей, есть тесты (очень даже приличное количество), работа с сетью, базой данных, есть многопоточность, есть и использование плагина BuildKonfig.

Само выступление можно посмотреть на youtube – Bottom-Up Code-Sharing with Kotlin Multiplatform - Russell Wolf, а код посмотреть на github – soluna.

Кстати, в выступлении упомянут один интересный факт – в AppCode и в IDEA Ultimate EAP можно отлаживать kotlin/native-код (это помимо того, что можно использовать lldb для установки breakpoint и плагин xcode-kotlin от touchlab).

#videos
Чтобы лучше понять, что такое Kotlin Multiplatform, чем эта технология отличается от того, что уже было до Kotlin и почему сейчас мы имеем то, что имеем, рекомендую посмотреть выступление Ильи Матвеева из JetBrains - Мультиплатформенные проекты в Kotlin 1.3 c Mobius 2019.

В выступлении рассказано почему решили делать новую технологию, чем она лучше #ifdef от C, какие проблемы получили пытаясь адаптировать gradle под mpp, как дальше их решали. Интересные вещи про поддержку mpp в IDE с пояснением проблем, о которых в работе особо не задумываешься.

#videos
Плагин для Xcode, позволяющий ставить breakpoint'ы в kotlin коде, получил обновление до Xcode 11.
Для установки нужно просто скачать актуальное состояние с master и запустить скрипт setup.

Помимо установки точек останова можно выводить использовать специальны скрипт для вывода данных из локальных переменных – konan_lldb.py для lldb (консоль отладчика в Xcode). Для его использования согласно документации по отладке Kotlin/Native нужно:
вызвать command script import <путь до konan_lldb.py, а после этого, используя p <имя переменной>, можно получать информацию о kotlin объектах.

#tips
Команда SuperAwesome разработала мобильное приложение Rukkaz для видео стримингового сервиса с использованием kotlin multiplatform. Про это они рассказали в своей статье – How we developed our new video platform Rukkaz as a cross-platform mobile app.

Само приложение можно скачать и посмотреть:
iOS
Android

Немного поглядев внутри apk, можно заметить, что используется как минимум ktor-client и coroutines, а это подсказывает что в общей библиотеке находится как минимум сетевой слой.

#cases #posts
Для упрощения поиска и подключения библиотек к kotlin проектам (и multiplatform в том числе) JetBrains выпустили плагин Package Search. Он позволяет прямо в конфигурации gradle запустить генерацию кода подключения зависимости с поиском нужной зависимости прямо в IDE. Цель – упростить поиск библиотек по примеру опыта NuGet.

На данный момент вышла EAP версия и нам доступно:
- Поддержка только groovy gradle (kotlin dsl в планах);
- Поиск по модулям, опубликованным на mavenCentral (в дальнейшем планируют расширить количество репозиториев);
- Индексация автоматическая – автору библиотеки не надо специально куда-то добавлять самому (но надо на поддерживаемый репозиторий залить – сейчас mavenCentral);
- В списке библиотек сразу выводится пометка о поддержке multiplatform;
- В multiplatform библиотеках перечисляются все поддерживаемые таргеты;
- Индексируется и информация с github - ссылка на репозиторий, звезды, форки, ридми, лицензия и прочее.

Пока не понятно как это будет работать с объявлением зависимостей в buildSrc, а так же для удобства работы с Kotlin/Native очень не хватает информации о версии kotlin, которую поддерживает выбранная версия библиотеки. А лучше и фильтры по версии, чтобы не искать среди кучи библиотек какая поддерживает используемую на проекте версию котлина.

#news
Скорей всего уже всем известно, что для работы с сетью в kotlin multiplatform доступна библиотека ktor. С ее помощью мы можем выполнять любые http запросы.

Если рассмотреть более специализированные решения, типа библиотек для REST API, то можно вспомнить про генерацию кода для ktor-client в moko-network из OpenAPI (Swagger) спецификации.
Еще помимо REST API есть популярный подход - GraphQL. И для этого тоже есть готовое решение - kgql позволяет из gql спецификации сгенерировать код для kotlinx.serialization, а далее останется только написать код вызова запроса (endpoint'ов то у graphql обычно как раз не много).

#libs