Пока нет горячих новостей продолжим обзор доступных библиотек. Не так давно появился плагин, который автоматически генерирует для корутин методы которые будут доступны на стороне iOS. Проблема с корутинами на айос не только в отсутствии многопоточности, но и в том что все suspend функции недоступны для вызова из swift (такой вид функций в swift не существует). А плагин при выставлении специальной аннотации автоматически сгенерирует код функции с калбеком, которая внутри уже вызывает suspend функцию. Тем кто хочет иметь доступ с натива до suspend функций - must have.
https://github.com/feilfeilundfeil/kotlin-native-suspend-function-callback
#libs
https://github.com/feilfeilundfeil/kotlin-native-suspend-function-callback
#libs
GitHub
GitHub - feilfeilundfeil/kotlin-native-suspend-function-callback: Kotlin Multiplatform compiler plugin to generate a callback implementation…
Kotlin Multiplatform compiler plugin to generate a callback implementation for suspended functions so they are visible from Kotlin Native - GitHub - feilfeilundfeil/kotlin-native-suspend-function-c...
Сегодня поделюсь недавно опубликованной презентацией доклада о kotlin multiplatform задевающей и сравнение с кроссплатформенными решениями, и создание приложения с стандартной функциональностью мобилок - работа с сетью, хранение данных локально, вывод данных пользователю. Основная ценность именно в наглядном и доступном примере - не "hello world", а с обычным функционалом мобильных приложений. В комплекте и сравнение техстека нативок и мультиплатформенной разработки, и сравнение языков, и отзывы айос разработчиков, и немного рекомендаций. Для тех кто с темой знакомится - рекомендую. Для тех кто уже разрабатывает на мультиплатформе - скорей всего нового ничего не будет (если только работа с sqldelight в новинку, ну и отзывы айосников).
https://speakerdeck.com/cmota/the-hitchhikers-guide-through-kotlin-multiplatform-extended
демо проект тут - https://github.com/cmota/droidconLX
#slides
https://speakerdeck.com/cmota/the-hitchhikers-guide-through-kotlin-multiplatform-extended
демо проект тут - https://github.com/cmota/droidconLX
#slides
Speaker Deck
The Hitchhikers Guide Through Kotlin Multiplatform Extended
Since the early days of mobile that we keep seeing new frameworks being designed to overcome one of the biggest challenges:
- How can I develop for both Android and iOS?
Although it’s initial promises, when we talk about performance, maintainability or…
- How can I develop for both Android and iOS?
Although it’s initial promises, when we talk about performance, maintainability or…
Обратим внимание на работу с датой и временем - в kotlin stdlib в версии kotlin 1.3.50 появились первые экспериментальные API для дальнейшей поддержки даты и времени в common коде. Это kotlin.time - https://kotlinlang.org/api/latest/jvm/stdlib/kotlin.time/index.html
На данный момент в API присутствует только функционал замера продолжительности времени (что совсем не покрывает полноценные задачи в проектах), но это всего первый шаг.
А пока официальное API прорабатывается (https://github.com/Kotlin/KEEP/blob/durations/proposals/stdlib/durations-and-clocks.md) для решения реальных задач на проектах можно использовать:
* https://github.com/korlibs/klock - позволяет парсить строку в дату и обратно, имеет работу с часовыми поясами и получать текущее время с устройства;
* https://github.com/lightningkite/lokalize - включает в себя и даты и время и продолжительность, работу с локалью (рендер времени/даты в локали устройства). Но не содержит поддержки часовых поясов;
* https://github.com/icerockdev/moko-core - позволяет получить таймштамп, а так же запускать таймеры в общем коде;
* https://github.com/ktorio/ktor (а именно ktor-utils) - содержит GMTDate и парсер дат в GMT. поддержки часовых поясов конечно нет, все приводится при парсинге в GMT, и форматирования кастомного нет, но для сети может хватать;
* свой вариант expect/actual - если никакая из библиотек не подошла, можно написать свои функции expect/actual и заиспользовать java.time.* и NSDate, делая так, как сделали бы на платформах при чистой нативной разработке (пример был в недавней статье - https://touchlab.co/expect-actuals-statements-kotlin-multiplatform/).
#libs
На данный момент в API присутствует только функционал замера продолжительности времени (что совсем не покрывает полноценные задачи в проектах), но это всего первый шаг.
А пока официальное API прорабатывается (https://github.com/Kotlin/KEEP/blob/durations/proposals/stdlib/durations-and-clocks.md) для решения реальных задач на проектах можно использовать:
* https://github.com/korlibs/klock - позволяет парсить строку в дату и обратно, имеет работу с часовыми поясами и получать текущее время с устройства;
* https://github.com/lightningkite/lokalize - включает в себя и даты и время и продолжительность, работу с локалью (рендер времени/даты в локали устройства). Но не содержит поддержки часовых поясов;
* https://github.com/icerockdev/moko-core - позволяет получить таймштамп, а так же запускать таймеры в общем коде;
* https://github.com/ktorio/ktor (а именно ktor-utils) - содержит GMTDate и парсер дат в GMT. поддержки часовых поясов конечно нет, все приводится при парсинге в GMT, и форматирования кастомного нет, но для сети может хватать;
* свой вариант expect/actual - если никакая из библиотек не подошла, можно написать свои функции expect/actual и заиспользовать java.time.* и NSDate, делая так, как сделали бы на платформах при чистой нативной разработке (пример был в недавней статье - https://touchlab.co/expect-actuals-statements-kotlin-multiplatform/).
#libs
Kotlin
kotlin.time - Kotlin Programming Language
Сегодня заденем тему отладки, а именно - отладки библиотеки написанной на Kotlin в iOS. В отличие от flutter, react native, xamarin и подобных - для отладки кода скомпилированного kotlin/native не требуется никакой специфичный отладчик. Достаточно Xcode и встроенного в него lldb. Например, используя следующую команду можно строчке в kotlin файле поставить breakpoint:
b -f hello.kt -l 1
И при остановке на этом месте Xcode корректно выведет стектрейс, с понятным именованием kotlin функций, даже тех что находятся внутри stdlib. Для упрощения установки breakpoint'ов в Touchlab сделали специальный плагин для Xcode, позволяющий открыть kotlin файл и поставить breakpoint так же просто как в swift файле - нажав слева от строки в Xcode. Также поддержка точек останова есть и в AppCode от JetBrains (с установленным плагином Kotlin/Native).
Единственное неудобство - локальные переменные доступные в скоупе функции, где мы остановились, не доступны для вывода информации о них. Но используя специальный python скрипт для отладчика - можно считать и их. Подробнее в разделе Variable Inspection в документации про отладку kotlin/native.
Подробнее про отладку и Variable Inspection - https://github.com/JetBrains/kotlin-native/blob/master/DEBUGGING.md
Статья с обзором плагина для Xcode - https://medium.com/hackernoon/kotlin-xcode-plugin-64f52ff8dc2a
Новость о добавлении поддержки Kotlin/Native в AppCode - https://blog.jetbrains.com/kotlin/2019/04/kotlinnative-support-for-appcode-2019-1/
#tips
b -f hello.kt -l 1
И при остановке на этом месте Xcode корректно выведет стектрейс, с понятным именованием kotlin функций, даже тех что находятся внутри stdlib. Для упрощения установки breakpoint'ов в Touchlab сделали специальный плагин для Xcode, позволяющий открыть kotlin файл и поставить breakpoint так же просто как в swift файле - нажав слева от строки в Xcode. Также поддержка точек останова есть и в AppCode от JetBrains (с установленным плагином Kotlin/Native).
Единственное неудобство - локальные переменные доступные в скоупе функции, где мы остановились, не доступны для вывода информации о них. Но используя специальный python скрипт для отладчика - можно считать и их. Подробнее в разделе Variable Inspection в документации про отладку kotlin/native.
Подробнее про отладку и Variable Inspection - https://github.com/JetBrains/kotlin-native/blob/master/DEBUGGING.md
Статья с обзором плагина для Xcode - https://medium.com/hackernoon/kotlin-xcode-plugin-64f52ff8dc2a
Новость о добавлении поддержки Kotlin/Native в AppCode - https://blog.jetbrains.com/kotlin/2019/04/kotlinnative-support-for-appcode-2019-1/
#tips
Немного про подключение kotlin/native фреймворка в ios приложение. Есть несколько путей:
1. Добавить в ios проекте отдельный таргет-фреймворк, который не будет иметь какого либо исходного кода, но будет содержать специальную build phase, в которой будет происходить вызов gradle task компиляции фреймворка, после чего результат компиляции будет копироваться в директорию сборки xcode - туда, куда бы сам xcode скомпилировал фреймворк будь тут исходный код swift'а. Это самый старый вариант интеграции.
2. Добавить в ios проекте фреймворк как embed фреймворк, указывая где он будет находиться - директория должна быть всегда одна, даже для разных архитектур фреймворка. Далее добавить к проекту build phase, которая будет вызывать у gradle специальную таску. Задача таски - собрать фреймворк и положить его по тому пути, который был указан при добавлении фреймворка в проект. Таким образом нет никаких лишних таргетов. Этот подход описан в текущем туториале от JetBrains "Targeting iOS and Android with Kotlin Multiplatform".
3. Интеграция через CocoaPods используя плагин org.jetbrains.kotlin.native.cocoapods. Для айосников он будет самый удобный. В gradle потребуется добавить специальную конфигурацию плагина (по сути описание pod'а нашего) и плагин автоматически сгенерирует нам podspec. После чего в Podfile от iOS приложения мы просто ссылаемся на наш pod локальный и вся интеграция готова. Под капотом все работает примерно так же как первый и второй случай - создается специальный проект для pod'а, там нет исходного кода но есть embed framework который собирается специальной gradle таской, которая и скомпилирует и перенесет фреймворк по нужному пути. Есть у этого решения пара особенностей - во первых на момент pod install фреймворк должен быть уже скомпилирован, то есть в градле мы должны засинхать проект и запустить gradle task :podspec в нашем mpp проекте. Во вторых - из gradle проекта не видны таски, используемые в xcode build phase (syncFramework в особенности). То есть запустить перекомпиляцию с переносом фреймворка куда-надо из вне xcode нельзя. А еще плагин позволяет подключать iOSные pod'ы в kotlin/native (только те у которых есть objc биндинг).
4. Интеграция через CocoaPods но без плагина org.jetbrains.kotlin.native.cocoapods. Разница в том, что podspec файл один раз пишется и кладется рядом с проектом, а градл таски syncFramework добавляются отдельно к проекту (у нас в IceRock это делает наш mobile-multiplatform плагин) и доступны для запуска просто из IDE или gradle. Это дает больше прозрачности при разработке и полный контроль над самой build phase сборки фреймворка (мы например кеширование на проектах через shell скрипт дополнительное делаем, чтобы не запускать gradle лишний раз при сборках ios проекта - он очень долгий).
Туториал Targeting iOS and Android with Kotlin Multiplatform - https://play.kotlinlang.org/hands-on/Targeting%20iOS%20and%20Android%20with%20Kotlin%20Multiplatform/
Плагин CocoaPods - https://kotlinlang.org/docs/reference/native/cocoapods.html
Плагин mobile-multiplatform - https://github.com/icerockdev/mobile-multiplatform-gradle-plugin
Пример интеграции mobile-multiplatform плагина (пока у него нет ридми) - https://github.com/icerockdev/moko-mvvm/tree/master/sample
#tips
1. Добавить в ios проекте отдельный таргет-фреймворк, который не будет иметь какого либо исходного кода, но будет содержать специальную build phase, в которой будет происходить вызов gradle task компиляции фреймворка, после чего результат компиляции будет копироваться в директорию сборки xcode - туда, куда бы сам xcode скомпилировал фреймворк будь тут исходный код swift'а. Это самый старый вариант интеграции.
2. Добавить в ios проекте фреймворк как embed фреймворк, указывая где он будет находиться - директория должна быть всегда одна, даже для разных архитектур фреймворка. Далее добавить к проекту build phase, которая будет вызывать у gradle специальную таску. Задача таски - собрать фреймворк и положить его по тому пути, который был указан при добавлении фреймворка в проект. Таким образом нет никаких лишних таргетов. Этот подход описан в текущем туториале от JetBrains "Targeting iOS and Android with Kotlin Multiplatform".
3. Интеграция через CocoaPods используя плагин org.jetbrains.kotlin.native.cocoapods. Для айосников он будет самый удобный. В gradle потребуется добавить специальную конфигурацию плагина (по сути описание pod'а нашего) и плагин автоматически сгенерирует нам podspec. После чего в Podfile от iOS приложения мы просто ссылаемся на наш pod локальный и вся интеграция готова. Под капотом все работает примерно так же как первый и второй случай - создается специальный проект для pod'а, там нет исходного кода но есть embed framework который собирается специальной gradle таской, которая и скомпилирует и перенесет фреймворк по нужному пути. Есть у этого решения пара особенностей - во первых на момент pod install фреймворк должен быть уже скомпилирован, то есть в градле мы должны засинхать проект и запустить gradle task :podspec в нашем mpp проекте. Во вторых - из gradle проекта не видны таски, используемые в xcode build phase (syncFramework в особенности). То есть запустить перекомпиляцию с переносом фреймворка куда-надо из вне xcode нельзя. А еще плагин позволяет подключать iOSные pod'ы в kotlin/native (только те у которых есть objc биндинг).
4. Интеграция через CocoaPods но без плагина org.jetbrains.kotlin.native.cocoapods. Разница в том, что podspec файл один раз пишется и кладется рядом с проектом, а градл таски syncFramework добавляются отдельно к проекту (у нас в IceRock это делает наш mobile-multiplatform плагин) и доступны для запуска просто из IDE или gradle. Это дает больше прозрачности при разработке и полный контроль над самой build phase сборки фреймворка (мы например кеширование на проектах через shell скрипт дополнительное делаем, чтобы не запускать gradle лишний раз при сборках ios проекта - он очень долгий).
Туториал Targeting iOS and Android with Kotlin Multiplatform - https://play.kotlinlang.org/hands-on/Targeting%20iOS%20and%20Android%20with%20Kotlin%20Multiplatform/
Плагин CocoaPods - https://kotlinlang.org/docs/reference/native/cocoapods.html
Плагин mobile-multiplatform - https://github.com/icerockdev/mobile-multiplatform-gradle-plugin
Пример интеграции mobile-multiplatform плагина (пока у него нет ридми) - https://github.com/icerockdev/moko-mvvm/tree/master/sample
#tips
Небольшой список библиотек kotlin multiplatform, покрывающий большинство базовых задач мобильной разработки:
* https://github.com/ktorio/ktor - http клиент, API построено coroutines. Заменяет Retrofit и Alamofire;
* https://github.com/Kotlin/kotlinx.coroutines - асинхронный код в синхронном стиле, вместо калбеков просто помечаем функцию suspend и компилятор добавит калбеки за нас. А сам код будет выглядеть как синхронный. Частично заменяет RxJava/RxSwift ну и калбеки разумеется;
* https://github.com/Kotlin/kotlinx.serialization - сериализация из/в json/cbor/protobuf, работает на аннотациях и кодогенерации. Заменяет gson/jackson/TRON/Codable;
* https://github.com/russhwolf/multiplatform-settings - постоянное key-value хранилище. По сути SharedPreferences/UserDefaults доступные в общем коде;
* https://github.com/cashapp/sqldelight - база данных SQLite доступная в общем коде, с генерацией типобезопасных API. Заменяет Room/Realm/CoreData;
* https://github.com/AAkira/Napier - логирование. Замена Timber/CocoaLumberjack;
* https://github.com/Kodein-Framework/Kodein-DI - внедрение зависимостей (решаются зависимости в рантайме, нет кодогенерации и проверки на этапе компиляции). Замена Dagger/Swinject;
* https://github.com/korlibs/klock - работа с датой и временем, с поддержкой таймзон и форматирования;
* https://github.com/icerockdev/moko-mvvm - компоненты для построения Presentation слоя на базе MVVM. ViewModel'и и LiveData для реактивного обновления UI;
* https://github.com/icerockdev/moko-resources - ресурсы локализации и изображения с доступом из общего кода, и генерацией под обе платформы из одного источника;
* https://github.com/icerockdev/moko-permissions - получение рантайм разрешений из общего кода.
#libs
* https://github.com/ktorio/ktor - http клиент, API построено coroutines. Заменяет Retrofit и Alamofire;
* https://github.com/Kotlin/kotlinx.coroutines - асинхронный код в синхронном стиле, вместо калбеков просто помечаем функцию suspend и компилятор добавит калбеки за нас. А сам код будет выглядеть как синхронный. Частично заменяет RxJava/RxSwift ну и калбеки разумеется;
* https://github.com/Kotlin/kotlinx.serialization - сериализация из/в json/cbor/protobuf, работает на аннотациях и кодогенерации. Заменяет gson/jackson/TRON/Codable;
* https://github.com/russhwolf/multiplatform-settings - постоянное key-value хранилище. По сути SharedPreferences/UserDefaults доступные в общем коде;
* https://github.com/cashapp/sqldelight - база данных SQLite доступная в общем коде, с генерацией типобезопасных API. Заменяет Room/Realm/CoreData;
* https://github.com/AAkira/Napier - логирование. Замена Timber/CocoaLumberjack;
* https://github.com/Kodein-Framework/Kodein-DI - внедрение зависимостей (решаются зависимости в рантайме, нет кодогенерации и проверки на этапе компиляции). Замена Dagger/Swinject;
* https://github.com/korlibs/klock - работа с датой и временем, с поддержкой таймзон и форматирования;
* https://github.com/icerockdev/moko-mvvm - компоненты для построения Presentation слоя на базе MVVM. ViewModel'и и LiveData для реактивного обновления UI;
* https://github.com/icerockdev/moko-resources - ресурсы локализации и изображения с доступом из общего кода, и генерацией под обе платформы из одного источника;
* https://github.com/icerockdev/moko-permissions - получение рантайм разрешений из общего кода.
#libs
GitHub
GitHub - ktorio/ktor: Framework for quickly creating connected applications in Kotlin with minimal effort
Framework for quickly creating connected applications in Kotlin with minimal effort - ktorio/ktor
Сегодня хочется поделиться видео записями выступлений на тему мобильной мультиплатформы с прошедшего Kotlin/Everywhere Minsk.
Интересное:
* Reaktive: реактивное программирование в Kotlin Multiplatform - про перенос Rx в мультиплатформу, с поддержкой смены потоков, разбор от авторов библиотеки (уже было чуть раньше в постах);
* Sliced but whole. A little adventure in multiplatform world - не сильно успешный опыт использования mpp, стоит и такие кейсы знать. Подсвечивает проблемы адаптации людей с градлом, разобран и фронтенд веб с kotlin2js, интероп Firebase ios фреймворка с kotlin/native. Итог от спикера - "не для продакшена". Если рассматривать мобильную разработку - по нашему опыту для продакшена уже полгода как готово :)
* iOS & Kotlin. Путь приложения от начала до публикации в AppStore - взгляд айосника на разработку с kotlin mpp, в кейсе когда айосник единственный разраб на проекте и андроид платформы пока еще нет;
* Kotlin Multiplatform с точки зрения бизнеса - тут понятно из названия. Минимум технической инфы, максимум мнения бизнеса (аутсорс) на технологию и опыт использования.
https://www.youtube.com/playlist?list=PL0SwNXKJbuNmNzTBowoiL7tem0-1gOsmo
#videos
Интересное:
* Reaktive: реактивное программирование в Kotlin Multiplatform - про перенос Rx в мультиплатформу, с поддержкой смены потоков, разбор от авторов библиотеки (уже было чуть раньше в постах);
* Sliced but whole. A little adventure in multiplatform world - не сильно успешный опыт использования mpp, стоит и такие кейсы знать. Подсвечивает проблемы адаптации людей с градлом, разобран и фронтенд веб с kotlin2js, интероп Firebase ios фреймворка с kotlin/native. Итог от спикера - "не для продакшена". Если рассматривать мобильную разработку - по нашему опыту для продакшена уже полгода как готово :)
* iOS & Kotlin. Путь приложения от начала до публикации в AppStore - взгляд айосника на разработку с kotlin mpp, в кейсе когда айосник единственный разраб на проекте и андроид платформы пока еще нет;
* Kotlin Multiplatform с точки зрения бизнеса - тут понятно из названия. Минимум технической инфы, максимум мнения бизнеса (аутсорс) на технологию и опыт использования.
https://www.youtube.com/playlist?list=PL0SwNXKJbuNmNzTBowoiL7tem0-1gOsmo
#videos
Затронем важную часть разработки, которая совсем не видна пользователям, но очень нужна разрабам - логирование. В мобильной мультиплатформе есть небольшой выбор библиотек:
* https://github.com/JakeWharton/timber - стандарт в Android разработке. Мультиплатформенная версия начата, но так и не закончена. Есть форк от Touchlab где доделана и айос версия (https://github.com/touchlab/timber/tree/native), но в bintray нет сборки с актуального котлина (можно просто скачать себе исходники и собрать самому себе в мавен репозиторий);
* https://github.com/AAkira/Napier - библиотека вдохновленная Timber'ом - поддержка обеих мобильных платформ из коробки, api примерно такое же как и у Timber. Так же возможно добавлять свои логгеры (зовутся Antilog). Поддерживает актуальнную версию kotlin;
* https://github.com/korlibs/klogger - мультиплатформенный логгер, без поддержки множества output'ов (как сделано у Timber и Napier) и пока без апдейта до актуального 1.3.50;
* https://github.com/florent37/Multiplatform-Log - самый простейший логгер, так же без поддержки множества output'ов. До актуальной версии kotlin так и не обновлено.
Если подвести краткий вывод - в MPP для логирования брать нужно Napier. Почти тот же Timber, но для всех платформ и не требуется самим пересобирать на новую версию котлина.
#libs
* https://github.com/JakeWharton/timber - стандарт в Android разработке. Мультиплатформенная версия начата, но так и не закончена. Есть форк от Touchlab где доделана и айос версия (https://github.com/touchlab/timber/tree/native), но в bintray нет сборки с актуального котлина (можно просто скачать себе исходники и собрать самому себе в мавен репозиторий);
* https://github.com/AAkira/Napier - библиотека вдохновленная Timber'ом - поддержка обеих мобильных платформ из коробки, api примерно такое же как и у Timber. Так же возможно добавлять свои логгеры (зовутся Antilog). Поддерживает актуальнную версию kotlin;
* https://github.com/korlibs/klogger - мультиплатформенный логгер, без поддержки множества output'ов (как сделано у Timber и Napier) и пока без апдейта до актуального 1.3.50;
* https://github.com/florent37/Multiplatform-Log - самый простейший логгер, так же без поддержки множества output'ов. До актуальной версии kotlin так и не обновлено.
Если подвести краткий вывод - в MPP для логирования брать нужно Napier. Почти тот же Timber, но для всех платформ и не требуется самим пересобирать на новую версию котлина.
#libs
GitHub
GitHub - JakeWharton/timber: A logger with a small, extensible API which provides utility on top of Android's normal Log class.
A logger with a small, extensible API which provides utility on top of Android's normal Log class. - JakeWharton/timber
Обратим внимание на еще один важный для разработки момент - Continuous Integration. Уже нельзя представить современный проект без CI, который как минимум должен автоматизировать деплой билдов, а в идеале - проводить и тестирование и проверку кода на правила разработки.
Что же меняется на CI относительно чисто нативных iOS и Android проектов, если мы начинаем использовать общую библиотеку на Kotlin MultiPlatform?
Ответ - практически ничего. Для android все остается также как было. Для iOS могут потребоваться некоторые изменения. Обратим внимание на них:
1. На раннере собирающем iOS должна быть java для корректного запуска gradle и компиляции kotlin/native;
2. При интеграции общей библиотеки через cocoapods перед вызовом pod install должен быть собран фреймворк (в официальном cocoapods плагине перед pod install нужно вызвать у gradle задачу podspec, а если использовать наш mobile-multiplatform плагин как в moko-template - можно просто вызывать pod install и все сделается само);
3. При интеграции общей библиотеки через билдфазу с отдельным таргетом в самом проекте - билдфаза сама запустит градл и все что нужно сделает, без необходимости делать что-то предварительно;
4. Для запуска тестов на айос пока требуется добавлять отдельную градл таску в конфигурацию общей библиотеки. Таска соберет запускаемый файл тестов и запустит его на симуляторе iOS.
У нас, в IceRock, для CI используется GitLab CI, раннер это mac-mini на котором и xcode и android sdk установлены, сборка android проекта делается полностью средствами градла, а сборка айос полностью средствами Fastlane.
Так же по этой теме есть неплохая статья https://diamantidis.github.io/2019/09/08/continuous-integration-for-kotlin-native-projects-with-gitlab-ci, в которой разобрана вся настройка CI для GitLab под проект с общей библиотекой, включая и запуск тестов и прогон lint. Статья входит в цикл статей про MPP - там есть и про настройку окружения, и про настройку юнит тестов, и про инструменты проверки кода. Есть и проект пример с этим всем https://gitlab.com/diamantidis_io/kmp_template/tree/master
Упомянуто:
https://kotlinlang.org/docs/reference/native/cocoapods.html - официальный gradle плагин cocoapods
https://github.com/icerockdev/mobile-multiplatform-gradle-plugin - gradle плагин для упрощения настройки mobile mpp проектов
https://github.com/icerockdev/moko-template - проект шаблон с использованием mobile-multiplatform плагина (примеры фичей и ридми пока в процессе)
#posts #tips
Что же меняется на CI относительно чисто нативных iOS и Android проектов, если мы начинаем использовать общую библиотеку на Kotlin MultiPlatform?
Ответ - практически ничего. Для android все остается также как было. Для iOS могут потребоваться некоторые изменения. Обратим внимание на них:
1. На раннере собирающем iOS должна быть java для корректного запуска gradle и компиляции kotlin/native;
2. При интеграции общей библиотеки через cocoapods перед вызовом pod install должен быть собран фреймворк (в официальном cocoapods плагине перед pod install нужно вызвать у gradle задачу podspec, а если использовать наш mobile-multiplatform плагин как в moko-template - можно просто вызывать pod install и все сделается само);
3. При интеграции общей библиотеки через билдфазу с отдельным таргетом в самом проекте - билдфаза сама запустит градл и все что нужно сделает, без необходимости делать что-то предварительно;
4. Для запуска тестов на айос пока требуется добавлять отдельную градл таску в конфигурацию общей библиотеки. Таска соберет запускаемый файл тестов и запустит его на симуляторе iOS.
У нас, в IceRock, для CI используется GitLab CI, раннер это mac-mini на котором и xcode и android sdk установлены, сборка android проекта делается полностью средствами градла, а сборка айос полностью средствами Fastlane.
Так же по этой теме есть неплохая статья https://diamantidis.github.io/2019/09/08/continuous-integration-for-kotlin-native-projects-with-gitlab-ci, в которой разобрана вся настройка CI для GitLab под проект с общей библиотекой, включая и запуск тестов и прогон lint. Статья входит в цикл статей про MPP - там есть и про настройку окружения, и про настройку юнит тестов, и про инструменты проверки кода. Есть и проект пример с этим всем https://gitlab.com/diamantidis_io/kmp_template/tree/master
Упомянуто:
https://kotlinlang.org/docs/reference/native/cocoapods.html - официальный gradle плагин cocoapods
https://github.com/icerockdev/mobile-multiplatform-gradle-plugin - gradle плагин для упрощения настройки mobile mpp проектов
https://github.com/icerockdev/moko-template - проект шаблон с использованием mobile-multiplatform плагина (примеры фичей и ридми пока в процессе)
#posts #tips
Ioannis Diamantidis
Continuous Integration for Kotlin Native projects with Gitlab CI
A post to document how to setup a GitLab CI pipeline that will run the code styling and unit test jobs for a Kotlin Native project that contains an iOS app, an Android app and a shared library.
При разговоре о мультиплатформенной разработке iOS разработчики обычно предполагают что это означает отказ от привычных им библиотек. В контексте Kotlin Multiplatform хочется развеять это заблуждение...
* Первый момент (и самый очевидный) - так как UI делается все так же в Swift, то разработчику доступны все нативные библиотеки как через CocoaPods так и Carthage;
* Второе - внутри самой общей библиотеки на Kotlin в ios-specific части тоже можно использовать зависимости из нативного мира - ограничение только в том что библиотека должна иметь objc биндинг (так как Kotlin/Native взаимодействует именно с objc). Вручную это делается через cinterop;
* Третье - для упрощения подключения iOS библиотек к kotlin ios-specific gradle плагин org.jetbrains.kotlin.native.cocoapods позволяет прям в gradle указать список pod'ов которые будут автоматически проброшены в kotlin. И в ios-specific части можно работать с подключенными библиотеками. У плагина есть пара ограничений (нет поддержки SubSpec и собирать библиотеку нужно будет обязательно через Xcode, так как для линковки все данные о подключенных Pod'ах именно у Xcode).
Документация по плагину - https://github.com/JetBrains/kotlin-native/blob/master/COCOAPODS.md
Ручное подключение библиотеки, без плагина - https://kotlinlang.org/docs/reference/building-mpp-with-gradle.html#cinterop-support
#tips
* Первый момент (и самый очевидный) - так как UI делается все так же в Swift, то разработчику доступны все нативные библиотеки как через CocoaPods так и Carthage;
* Второе - внутри самой общей библиотеки на Kotlin в ios-specific части тоже можно использовать зависимости из нативного мира - ограничение только в том что библиотека должна иметь objc биндинг (так как Kotlin/Native взаимодействует именно с objc). Вручную это делается через cinterop;
* Третье - для упрощения подключения iOS библиотек к kotlin ios-specific gradle плагин org.jetbrains.kotlin.native.cocoapods позволяет прям в gradle указать список pod'ов которые будут автоматически проброшены в kotlin. И в ios-specific части можно работать с подключенными библиотеками. У плагина есть пара ограничений (нет поддержки SubSpec и собирать библиотеку нужно будет обязательно через Xcode, так как для линковки все данные о подключенных Pod'ах именно у Xcode).
Документация по плагину - https://github.com/JetBrains/kotlin-native/blob/master/COCOAPODS.md
Ручное подключение библиотеки, без плагина - https://kotlinlang.org/docs/reference/building-mpp-with-gradle.html#cinterop-support
#tips
Forwarded from Nikolay
Небольшое дополнение - можно взаимодействовать и с библиотеками написанными на Си, а также возможно работать и в другую сторону, экспортируя Котлин в виде Objective-C или C деклараций.
Наконец-то опубликованы видео с прошедшего DroidCon New York, на котором было очень много внимания уделено именно Kotlin Multiplatform в мобильной разработке. Что есть:
* Native Concurrency and Coroutines - от автора библиотеки CoroutineWorker , которая позволяет выполнять suspend функции на отдельных потоках - как появилась библиотека и как используется в Autodesk;
* Multiplatform Library Development - от автора библиотеки multiplatform-settings - про разработку mpp библиотеки, про проектирование апи под обе платформы, про состояние kotlin mpp на данный момент;
* Lessons Learned from Using Kotlin Multiplatform internally - опыт погружения андроид и айос специалистов в мультиплатформу, какие шишки набивали, какие выводы сделали, фидбек айосников;
* Effective Multiplatform Architecture - очень классная презентация с полезными аргументами как продать мпп бизнесу, так и для технарей с полезными идеями как вводить мультиплатформу в существующий проект;
* Multiplatform Functional Architecture - про архитектуру MVU (Model-View-Update) на мультиплатформе. Библиотека oolong поможет строить такую архитектуру. Для любителей Redux;
* SwiftUI meets Kotlin Multiplatform! - небольшой доклад про то как дружили общую библиотеку и SwiftUI. Для этого предложено и ViewModel'и унести на сторону нативного android, ios кода;
* Using Kotlin/JS and Kotlin/Native on Android - доклад от Jake Wharton о том как на андроиде он дружил обычный котлин, нативный котлин и kotlin js в одном приложении;
* Building apps using Kotlin Native - расказ про разработку общей библиотеки, для новичков в теме. Даже задета тема про Worker'ы для многопоточности на Native.
#videos
* Native Concurrency and Coroutines - от автора библиотеки CoroutineWorker , которая позволяет выполнять suspend функции на отдельных потоках - как появилась библиотека и как используется в Autodesk;
* Multiplatform Library Development - от автора библиотеки multiplatform-settings - про разработку mpp библиотеки, про проектирование апи под обе платформы, про состояние kotlin mpp на данный момент;
* Lessons Learned from Using Kotlin Multiplatform internally - опыт погружения андроид и айос специалистов в мультиплатформу, какие шишки набивали, какие выводы сделали, фидбек айосников;
* Effective Multiplatform Architecture - очень классная презентация с полезными аргументами как продать мпп бизнесу, так и для технарей с полезными идеями как вводить мультиплатформу в существующий проект;
* Multiplatform Functional Architecture - про архитектуру MVU (Model-View-Update) на мультиплатформе. Библиотека oolong поможет строить такую архитектуру. Для любителей Redux;
* SwiftUI meets Kotlin Multiplatform! - небольшой доклад про то как дружили общую библиотеку и SwiftUI. Для этого предложено и ViewModel'и унести на сторону нативного android, ios кода;
* Using Kotlin/JS and Kotlin/Native on Android - доклад от Jake Wharton о том как на андроиде он дружил обычный котлин, нативный котлин и kotlin js в одном приложении;
* Building apps using Kotlin Native - расказ про разработку общей библиотеки, для новичков в теме. Даже задета тема про Worker'ы для многопоточности на Native.
#videos
Сегодня поделюсь статьей, которую возможно уже видели в сети, но она имеет очень интересную информацию. Статья про разработку библиотеки kissme - не про поцелуи, а про хранение данных в keychain. Помимо просто истории о разработке multiplatform библиотеки и столкновением с некоторыми ограничениями, тут есть то что не часто встретишь - линковка objective-c библиотеки в kotlin код. У ребят как раз был кейс, что не смогли через kotlin ios-specific код сделать нужную функциональность и поэтому решили сделать дополнительно objective-c библиотеку, которую прилинковали к котлину через cinterop и в итоге вызывали из котлина функции своей библиотеки.
Kissme: Kotlin Secure Storage Multiplatform library. The Code Story.
#posts #libs
Kissme: Kotlin Secure Storage Multiplatform library. The Code Story.
#posts #libs
GitHub
GitHub - netguru/Kissme: Kissme: Kotlin Secure Storage Multiplatform
Kissme: Kotlin Secure Storage Multiplatform. Contribute to netguru/Kissme development by creating an account on GitHub.
Сегодня у нас пост новостей от JetBrains.
Kotlin/Native в следующем релизе получит:
* поддержка Xcode 11
* новый LLVM
* новые API iOS, macOS
* поддержка watchOS и tvOS.
Подробнее тут - https://github.com/JetBrains/kotlin-native/pull/3391
Попробовать можно будет уже скоро - EAP планируется в ближайшие недели.
Так же вы можете задать вопросы про новый релиз напрямую авторам в нашем чатике - нажимайте Discuss и обращайтесь - Николай Иготти уже там (новость как раз от него).
#news
Kotlin/Native в следующем релизе получит:
* поддержка Xcode 11
* новый LLVM
* новые API iOS, macOS
* поддержка watchOS и tvOS.
Подробнее тут - https://github.com/JetBrains/kotlin-native/pull/3391
Попробовать можно будет уже скоро - EAP планируется в ближайшие недели.
Так же вы можете задать вопросы про новый релиз напрямую авторам в нашем чатике - нажимайте Discuss и обращайтесь - Николай Иготти уже там (новость как раз от него).
#news
Ioannis Diamantidis продолжает свою серию статей о Kotlin/Native. Новая статья From Kotlin to Native: Or how Kotlin concepts are mapped to the Apple framework разбирает некоторые особенности получаемого из Kotlin кода iOS фреймворка - как Kotlin код выглядит из ObjectiveC и Swift.
Это не полный список особенностей на стыке Kotlin и ObjC, но знать их очень полезно. Так же еще особенности можно подсмотреть в нашей летней статье - Опыт работы с Kotlin Multiplatform за 10 месяцев. Краткий список особенностей kotlin на стыке с ios доступен в презентации.
Так же в октябре на AppsConf мы отметим еще несколько новых особенностей по актуальной версии Kotlin.
#posts #slides
Это не полный список особенностей на стыке Kotlin и ObjC, но знать их очень полезно. Так же еще особенности можно подсмотреть в нашей летней статье - Опыт работы с Kotlin Multiplatform за 10 месяцев. Краткий список особенностей kotlin на стыке с ios доступен в презентации.
Так же в октябре на AppsConf мы отметим еще несколько новых особенностей по актуальной версии Kotlin.
#posts #slides
Ioannis Diamantidis
From Kotlin to Native: Or how Kotlin concepts are mapped to the Apple framework
TL;DR This post is about how some specific Kotlin features are compiled to Objective-C and how they can be used in a Swift project when using Kotlin Native to build an Apple framework.
Можно ли работать с базой данных из common кода под ios и android? Ответ - конечно можно :) И есть несколько путей:
1. Метод "в лоб" - делаем interface реализация которого будет проброшена с нативной стороны и на android и ios делаем отдельные реализации БД так, как привыкли разработчики;
2. Делаем expect/actual классы, чтобы уже внутри котлина реализовать всю работу с БД, используя нативные средства Android и iOS в actual реализациях;
3. Используем библиотеку SQLiter которая позволяет в common коде работать с sqlite БД напрямую, без каких либо оберток;
4. Используем библиотеку SQLDelight от известных square (которые успели переименоваться в cashapp). Данная библиотека идет в паре с gradle plugin'ом который из специального файла, в котором описана схема базы данных и запросы, которые планируется выполнять, генерирует сущности и методы для выполнения запросов. И все это доступно из common кода для обеих мобильных платформ, а так же уже проверено на Android годами ранее.
Рекомендуемый на данный момент способ это конечно SQLDelight. Для знакомства с ним можно воспользоваться:
* Презентацией SELECT * SQLDelight JOIN Multiplatform в которой разобраны преимущества библиотеки;
* Статьей SQLDelight 1.x Quick Start Guide for Android с пошаговой инструкцией и даже примером юниттестирования;
* Статьей Kotlin Multiplatform. Very beginner’s guide (part 3) Database с пошаговым примером реализации БД, но статья со времен kotlin 1.3.31, так что возможны некоторые нестыковки, особенно по версиям библиотек используемых - с 1.3.50 на айос не сойдутся они, нужно более новые;
* Проектом Droidcon Lisbon - здесь в app есть common source set и используется SQLDelight с версией kotlin 1.3.41;
* Проектом Newsout тоже на версии kotlin 1.3.41.
А еще SQLDelight поддерживает Flow для оповещения о изменениях, но на iOS там есть проблемы, требующие обхода.
#libs #slides #projects
1. Метод "в лоб" - делаем interface реализация которого будет проброшена с нативной стороны и на android и ios делаем отдельные реализации БД так, как привыкли разработчики;
2. Делаем expect/actual классы, чтобы уже внутри котлина реализовать всю работу с БД, используя нативные средства Android и iOS в actual реализациях;
3. Используем библиотеку SQLiter которая позволяет в common коде работать с sqlite БД напрямую, без каких либо оберток;
4. Используем библиотеку SQLDelight от известных square (которые успели переименоваться в cashapp). Данная библиотека идет в паре с gradle plugin'ом который из специального файла, в котором описана схема базы данных и запросы, которые планируется выполнять, генерирует сущности и методы для выполнения запросов. И все это доступно из common кода для обеих мобильных платформ, а так же уже проверено на Android годами ранее.
Рекомендуемый на данный момент способ это конечно SQLDelight. Для знакомства с ним можно воспользоваться:
* Презентацией SELECT * SQLDelight JOIN Multiplatform в которой разобраны преимущества библиотеки;
* Статьей SQLDelight 1.x Quick Start Guide for Android с пошаговой инструкцией и даже примером юниттестирования;
* Статьей Kotlin Multiplatform. Very beginner’s guide (part 3) Database с пошаговым примером реализации БД, но статья со времен kotlin 1.3.31, так что возможны некоторые нестыковки, особенно по версиям библиотек используемых - с 1.3.50 на айос не сойдутся они, нужно более новые;
* Проектом Droidcon Lisbon - здесь в app есть common source set и используется SQLDelight с версией kotlin 1.3.41;
* Проектом Newsout тоже на версии kotlin 1.3.41.
А еще SQLDelight поддерживает Flow для оповещения о изменениях, но на iOS там есть проблемы, требующие обхода.
#libs #slides #projects
Тем кто интересуется темой тестирования кода будет полезна статья Shared Library in Kotlin Multiplatform в которой разобрано по шагам создание общей библиотеки и добавление к ней простых тестов.
В паре с статьей идет и проект-пример, в котором можно наглядно посмотреть и тесты и демо приложение, работающее с сетью (ktor-client, kotlinx.serialization, coroutines - стандартный mpp набор).
Еще примеры тестов можно посмотреть в проекте-примере от russwolf (автор multiplatform-settings) и в еще одном проекте примере.
#posts #samples #tests
В паре с статьей идет и проект-пример, в котором можно наглядно посмотреть и тесты и демо приложение, работающее с сетью (ktor-client, kotlinx.serialization, coroutines - стандартный mpp набор).
Еще примеры тестов можно посмотреть в проекте-примере от russwolf (автор multiplatform-settings) и в еще одном проекте примере.
#posts #samples #tests
Karumi Blog
Shared Library in Kotlin Multiplatform
Explaining our experience with the shared library in Kotlin Multiplatform.
Badoo продолжает радовать контентом по Kotlin Multiplatform. В этот раз подготовили хоршую подробную статью по настройке автосборки для мультиплатформенной библиотеки - Continuous delivery для вашей Kotlin Multiplatform библиотеки. Стоит ознакомиться со статьей даже тем, кто не собирается настраивать CI/CD, так как помимо конфигурации для автоматической сборки и выгрузки в maven репозиторий через Travis CI всех таргетов библиотеки, там описано и строение публикуемых данных - особенно интересно про Gradle Metadata, что так активно используется Kotlin Multiplatform проектами. Всем бы авторам MPP библиотек настроить автоматизацию на github по примеру ребят, чтобы апдейты к библиотекам выходили как можно быстрее, после релиза новой версии котлина.
#posts #libs
#posts #libs
Хабр
Continuous delivery для вашей Kotlin Multiplatform библиотеки
Привет! Меня зовут Юрий Влад, я Android-разработчик в компании Badoo и принимаю участие в создании библиотеки Reaktive — Reactive Extensions на чистом Kotlin. В...
А для тех кто уже успел ознакомиться со статьей от 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
Примеры использования trikot.streams выглядят очень похожими на LiveData, как в moko-mvvm, при чем так же есть конвертация stream в LiveData для android, а для iOS сделан дополнительный cocoapod с вспомогательными swift методами привязки stream к элементам на экране (как и в moko-mvvm).
#libs
GitHub
GitHub - mirego/trikot.streams: Reactive Streams for Kotlin Multiplatform with mutability checks
Reactive Streams for Kotlin Multiplatform with mutability checks - GitHub - mirego/trikot.streams: Reactive Streams for Kotlin Multiplatform with mutability checks