Kotlin Multiplatform
2.62K subscribers
84 photos
3 videos
407 links
Русскоязычный канал новостей о Kotlin Multiplatform
Download Telegram
На одном из наших проектов, который мы делали с использованием 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
Опрос показал, что половина участников пока только знакомится с информацией и статьями, но не пробовали kotlin multiplatform в разработке мобильных приложений.

На грядущие выходные есть полезные материалы для этой половины:
1. На github доступен шаблон проекта moko-template, который позволяет быстро начать разработку мобильного приложения с mpp внутри, имеет подключенные moko-библиотеки и пример из пары фич (архитектура проекта многомодульная, что положительно сказывается на времени пересборки ios-таргета);
2. В дополнение к moko-template доступны codelab'ы, в которых разобрано создание приложения просмотра списка GIF'ок на основе moko-template;
3. На kmp.icerock.dev можно найти множество ссылок на полезные статьи, важные блоки документации kotlin про mpp, полезные библиотеки как официальные так и от сообщества, проекты примеры.

Надеюсь эти материалы помогут вам попробовать технологию и упростят изучение.
Ошибки/предложения по можно писать в issues на github (moko-template, codelabs, kmp).

#tips
Советы из опыта

suspend-функции в публичном интерфейсе библиотеки, которая компилируется в iOS framework, автоматически стираются. Это происходит потому что в objective-c (и swift) нет аналога suspend-функций. По этой причине рекомендуется держать всю работу с kotlin-coroutines внутри kotlin.

Если же требуется вызывать suspend-функцию из swift/objective-c, то можно в ios-specific коде сделать экстеншен-функцию принимающую callback, а внутри функции запускать корутину например на GlobalScope. При чем это можно делать не вручную, а использовать плагин, генерирующий такую функцию автоматически, например - Recast, kotlin-native-suspend-function-callback.

#tips
Android Framework накладывает на android-разработчика множество ограничений из-за сложного жизненного цикла компонентов системы:
- Activity пересоздаются при поворотах экрана, при смене языка системы, что не происходит на iOS.
- Приложение может быть выключено системой почти в любой момент из-за нехватки памяти, но когда пользователь решит вернуться в приложение через "карусель" приложений - он должен попасть туда же, где и был (и фреймворк предлагает специальные механизмы под это).

Для передачи данных между пересозданиями Activity (или просто при переходе на новый экран) часто используется Parcelable - специальный механизм сериализации данных, разработанный для android. И android-разработчики часто его используют, а потому и в multiplatform библиотеке отказаться от него не хотелось бы. Об этом и пишет Ankush Gupta в своей статье - Using @Parcelize in Kotlin Multiplatform.

А для тех, кто хотел бы подключить себе готовую реализацию в проект - есть moko-parcelize.

#posts #libs
Вышла новая библиотека для работы со временем - island-time. Отличается она от существующих multiplatform библиотек тем, что планируется воспроизвести доступный в java.time функционал.

Что доступно:
* Работа с датами и временем, с учетом таймзон;
* Работа с таймзонами;
* Работа с периодами и отрезками времени;
* Парсинг строки в дату (включая и нестандартные форматы).

Пока нет:
* Стабильного релиза (сейчас активная фаза разработки с SNAPSHOT'ами);
* Форматирование даты в строку.

#libs
Kaskade - еще одна библиотека с архитектурными компонентами. Позволяет реализовывать unidirectional data flow.

Поддерживается последняя версия kotlin - 1.3.50, платформы JVM, iOS, JS. Имеет интеграции с coroutines, livedata, rxjava.

На примере android приложения разобрана работа с библиотекой в статье Managing states with Kaskade

#libs #posts
Советы из опыта

При компиляции Kotlin в iOS-framework нужно учитывать, что abstract class'ы станут в Objective-C (и Swift) обычными классами. Это происходит из-за того, что в Objective-C и Swift нет абстрактных классов. Поэтому Xcode при компиляции никак не проверит реализовал ли разработчик абстрактный метод или нет. Если абстрактный метод останется не реализованным то в рантайме будет выброшено исключение.

Рекомендуется просто не выносить абстрактные классы в публичный интерфейс. Их можно использовать внутри kotlin, а наружу можно выдать интерфейс, который требуется с нативной стороны реализовать.

#tips