По мотивам прошедших дебатов хотелось бы обсудить плюсы и минусы Flutter в сравнении с KMP и Compose Multiplatform для разработки мобильных приложений.
👍 Плюсы Flutter
▫️ Высокопроизводительный графический движок Impeller
▫️ Очень простой порог входа
▫️ Куча готовых плагинов
▫️ На сегодняшний день гораздо популярнее KMP
▫️ В релизе с 2018 года, в отличие от вышедшего в этом году в релиз KMP и тем более Compose MP for iOS, который все ещё в альфе
▫️ Flutter на iOS работает быстрее и стабильнее, чем Compose для iOS на сегодняшний день
▫️ Есть киллер фичи Hot Reload / Hot Restart ускоряющие разработку
▫️ На Flutter можно официально разрабатывать под Аврору и Фуксию (зачем — это уже другой вопрос)
👎 Минусы Flutter
🔸 Очень больно переводить существующий проект на Flutter, с KMP это можно делать просто и постепенно
🔸 Dart по сравнению с Kotlin выглядит очень устаревшим, приходится писать гораздо больше кода
🔸 Многопоточность в Dart с изолятами довольно ограничена по сравнению с возможностями и гибкостью корутин в Kotlin
🔸 Верстка одного и того же экрана на Flutter получается примерно в 2 раза больше чем на Compose
🔸 Более примитивная система сборки по сравнению с Gradle
🔸 Кодогенерацию нельзя органично встроить в процесс сборки, про компиляторные плагины даже речи не идёт
🔸 Нетипобезопасные платформенные каналы, все креши будут в рантайме, если где-то ошибётесь (но есть альтернатива в виде Pigeon)
🔸 Множество публичных плагинов спорного качества
🔸 Нет официального решения для организации многомодульного проекта (есть только инструмент Melos)
🔸 Dart используется только во Flutter, в отличие от Kotlin, который используется в различных областях
Это все моменты, что я смог вспомнить, если у вас есть что добавить, то не стесняйтесь писать свои мысли в комментариях⌨️
#Flutter #KMP
Это все моменты, что я смог вспомнить, если у вас есть что добавить, то не стесняйтесь писать свои мысли в комментариях
#Flutter #KMP
Please open Telegram to view this post
VIEW IN TELEGRAM
iOS библиотеки в Kotlin коде
Не все знают, что в KMP мы не только можем скомпилировать Kotlin код в iOS фреймворк, но и, наоборот, использовать сторонние iOS библиотеки в Kotlin коде.
▶️ Например, есть две нативные библиотеки под Android и iOS, и вы хотите объединить их в одну KMP библиотеку и сделать все на Kotlin, тогда у вас есть два пути:
1️⃣ Использовать cocoapods (сторонний менеджер зависимостей в iOS), тогда подключение iOS фреймворка делается в одну строчку кода
2️⃣ Подключать фреймворк вручную, но тут все намного сложнее
Проблема cocoapods в том, что недавно их перевели в режим поддержки и большинство iOS разработчиков мигрируют свои зависимости на официальное решение SPM (Swift Package Manager), поэтому пойдем по второму пути и подключим iOS framework вручную:
1. Необходимо создать файл с расширением .def, где опишем некоторые параметры:
2. В build.gradle вашей библиотеки необходимо добавить конфигурацию для создания klib из фреймворка с помощью cinterop🤯 :
Сделать это необходимо для всех iOS таргетов❗️ Также как и в следующем шаге.
3. В build.gradle файле, где будете собирать итоговый фреймворк для iOS нужно прилинковать тот же фреймворк:
💡 Как видите, делается это довольно сложно, поэтому не рекомендую использовать сторонние iOS библиотеки в Kotlin коде, лучше в общем коде сделать интерфейс, а реализацию оставить нативной на каждой платформе.
❌ А еще если в iOS проекте уже использовалась эта библиотека, но другой версии, то все конечно же развалится 😂
#KMP #Kotlin #iOS
@kotlin_adept
Не все знают, что в KMP мы не только можем скомпилировать Kotlin код в iOS фреймворк, но и, наоборот, использовать сторонние iOS библиотеки в Kotlin коде.
Проблема cocoapods в том, что недавно их перевели в режим поддержки и большинство iOS разработчиков мигрируют свои зависимости на официальное решение SPM (Swift Package Manager), поэтому пойдем по второму пути и подключим iOS framework вручную:
1. Необходимо создать файл с расширением .def, где опишем некоторые параметры:
language = Objective-C
modules = YourFrameworkName
package = YourFrameworkName
2. В build.gradle вашей библиотеки необходимо добавить конфигурацию для создания klib из фреймворка с помощью cinterop
KotlinNativeTarget.compilations.getByName("main") {
val YourFramework by cinterops.creating {
defFile = project.file("src/nativeInterop/cinterop/YourFramework.def")
compilerOpts("-framework", "YourFramework", "-F${projectDir}/../YourFramework.xcframework/$frameworkArch/")
compilerOpts("-fmodules")
}
}
Сделать это необходимо для всех iOS таргетов
3. В build.gradle файле, где будете собирать итоговый фреймворк для iOS нужно прилинковать тот же фреймворк:
KotlinNativeTarget.binaries.all {
linkerOpts("-framework", "YourFramework", "-F${projectDir}/../YourFramework.xcframework/$frameworkArch/")
}
#KMP #Kotlin #iOS
@kotlin_adept
Please open Telegram to view this post
VIEW IN TELEGRAM
Как вкатиться в KMP без MacOs
Сегодня, слушая доклад Никиты Куликова на Podlodka Android Crew, получил для себя интересный инсайт.
Довольно часто видел вопросы в стиле, как мне вкатиться в Kotlin Multiplatform, если под рукой нет мака? Ведь на другой ОС запустить приложение под iOS не выйдет.
Решение довольно интересное, GitHub предоставляет вам бесплатное и безлимитное использование разных раннеров для Open source проектов, в том числе и на MacOs, соответственно вы можете собирать iOS проекты на CI и затем тестировать их на iPhone, если он у вас конечно есть🙃
Если хотите больше таких инсайтов и интересных обсуждений с разными экспертами, то вы ещё успеваете залететь на конференцию со скидкой по промокоду android_crew_12_o1TLih😉
#KMP
@kotlin_adept
Сегодня, слушая доклад Никиты Куликова на Podlodka Android Crew, получил для себя интересный инсайт.
Довольно часто видел вопросы в стиле, как мне вкатиться в Kotlin Multiplatform, если под рукой нет мака? Ведь на другой ОС запустить приложение под iOS не выйдет.
Решение довольно интересное, GitHub предоставляет вам бесплатное и безлимитное использование разных раннеров для Open source проектов, в том числе и на MacOs, соответственно вы можете собирать iOS проекты на CI и затем тестировать их на iPhone, если он у вас конечно есть
Если хотите больше таких инсайтов и интересных обсуждений с разными экспертами, то вы ещё успеваете залететь на конференцию со скидкой по промокоду android_crew_12_o1TLih
#KMP
@kotlin_adept
Please open Telegram to view this post
VIEW IN TELEGRAM
This media is not supported in your browser
VIEW IN TELEGRAM
Пока готовился к докладу, нашел неплохой репозиторий с набором разных анимаций для Compose Multiplatform.
Там вы найдете множество разных примеров:
🟣 Анимации заставок разных приложений (Netflix, Twitter, GitHub, Slack и др.)
🟣 Кастомный pull-to-refresh
🟣 Анимация горения свечи
🟣 Упоротая сова из Duolingo
А если вы iOS разработчик, то вот вам еще более классный репозиторий с кучей красивых анимаций для SwiftUI💅
#Animation #Compose #KMP #SwiftUI
@kotlin_adept
Там вы найдете множество разных примеров:
А если вы iOS разработчик, то вот вам еще более классный репозиторий с кучей красивых анимаций для SwiftUI
#Animation #Compose #KMP #SwiftUI
@kotlin_adept
Please open Telegram to view this post
VIEW IN TELEGRAM
Коллега из Контура, Василий Рылов, поделился архитектурным примером KMP проекта 🔥
В репозитории вы найдете пример приложения построенного по следующим принципам:
🟣 Каждая фича представлена группой модулей: feature-component, feature-domain, feature-ui и feature-data
🟣 Комбинация FSM-based MVI и MVVM+ подхода с простой небиблиотечной ViewModel
🟣 Навигация абстрагирована от Decompose, Decompose компоненты выделены в собственные модули
🟣 Многомодульный DI, каждый модуль может использовать собственную реализацию DI
В примере использованы библиотеки:
🔵 Multiplatform Room
🔵 Multiplatform Settings
🔵 Decompose
🔵 Compose Multiplatform
🔵 Варианты с Kotlin-inject и Koin DI
#KMP #Decompose #Sample
@kotlin_adept
В репозитории вы найдете пример приложения построенного по следующим принципам:
В примере использованы библиотеки:
#KMP #Decompose #Sample
@kotlin_adept
Please open Telegram to view this post
VIEW IN TELEGRAM
SwiftExport
Вчера вышел Kotlin 2.1, и мы стали еще на один шаг ближе к тому, чтобы отказаться от прослойки с Objective-C хедерами и использовать скомпилированный Kotlin-код напрямую в Swift😎
Но интересно даже не это — теперь, наконец, станет возможным разделять код на разные модули для Swift. Раньше все фичи, использующие KMP, могли обращаться к любой его части, а теперь это можно инкапсулировать.
🐱 Посмотреть пример кода можно здесь.
P.S. Я же очень жду возможность использования нескольких KMP библиотек в одном Swift проекте без создания umbrella модуля, чтобы была возможность переиспользовать рантайм Kotlin Native и общие библиотеки.
#KMP #Swift
@kotlin_adept
Вчера вышел Kotlin 2.1, и мы стали еще на один шаг ближе к тому, чтобы отказаться от прослойки с Objective-C хедерами и использовать скомпилированный Kotlin-код напрямую в Swift
Но интересно даже не это — теперь, наконец, станет возможным разделять код на разные модули для Swift. Раньше все фичи, использующие KMP, могли обращаться к любой его части, а теперь это можно инкапсулировать.
P.S. Я же очень жду возможность использования нескольких KMP библиотек в одном Swift проекте без создания umbrella модуля, чтобы была возможность переиспользовать рантайм Kotlin Native и общие библиотеки.
#KMP #Swift
@kotlin_adept
Please open Telegram to view this post
VIEW IN TELEGRAM
Как подключить KMP в iOS проект без CocoaPods
Я задумался об этом еще в прошлом году и подключил всё, как описано в инструкции. Но как только в Xcode-проекте появились кастомные конфигурации, начало происходить нечто странное...
Проект продолжал компилироваться, но при этом все новые изменения в общем коде перестали отображаться в Xcode. А если почистить кеш, то и вовсе выводилась ошибка: "No such module Shared". Я поспрашивал в чате, сталкивался ли кто-то с подобной проблемой, но узнал лишь, что с CocoaPods всё работает хорошо. Поэтому я просто забил и перешел на CocoaPods, думая, что, если проблема есть, её наверняка исправят🔥
Однако CocoaPods стали deprecated, и вся наша iOS-команда уже давно мигрировала на SPM. Представьте лица iOS-разработчиков, к которым вы не только притащили KMP, но еще и хотите заставить их вернуться на CocoaPods👍
Поэтому я снова вернулся к этой задаче и, к моему удивлению, спустя год ничего не изменилось: проблема всё ещё присутствует даже на новых версиях. Я стал разбираться и выяснил, что по каким-то причинам Xcode визуально подтягивает только фреймворк по пути build/xcode-frameworks/debug. Но путь для сборки фреймворка меняется, как только появляются кастомные конфигурации, и отвечает за это переменная окружения CONFIGURATION.
Тут я подумал: а зачем нам вообще разделять на разные папки для каждой конфигурации? В любом случае каждую конфигурацию мы маппим в Debug или Release build type с помощью переменной KOTLIN_FRAMEWORK_BUILD_TYPE.
Поэтому я для себя сделал следующий workaround. В Build Phase в Xcode, где собирается Kotlin-фреймворк, нужно переопределить переменную окружения конфигурации:
Таким образом, для всех конфигураций, которые маппятся в Debug, всё будет работать, а для релизных конфигураций нам важнее успешная сборка, нежели подсветка кода в Xcode.
Официального ответа по этому issue я всё ещё не получил, поэтому поддержите лайком, чтобы команда JetBrains заметила и дала официальные рекомендации.
#KMP #Xcode #iOS
@kotlin_adept
Я задумался об этом еще в прошлом году и подключил всё, как описано в инструкции. Но как только в Xcode-проекте появились кастомные конфигурации, начало происходить нечто странное...
Проект продолжал компилироваться, но при этом все новые изменения в общем коде перестали отображаться в Xcode. А если почистить кеш, то и вовсе выводилась ошибка: "No such module Shared". Я поспрашивал в чате, сталкивался ли кто-то с подобной проблемой, но узнал лишь, что с CocoaPods всё работает хорошо. Поэтому я просто забил и перешел на CocoaPods, думая, что, если проблема есть, её наверняка исправят
Однако CocoaPods стали deprecated, и вся наша iOS-команда уже давно мигрировала на SPM. Представьте лица iOS-разработчиков, к которым вы не только притащили KMP, но еще и хотите заставить их вернуться на CocoaPods
Поэтому я снова вернулся к этой задаче и, к моему удивлению, спустя год ничего не изменилось: проблема всё ещё присутствует даже на новых версиях. Я стал разбираться и выяснил, что по каким-то причинам Xcode визуально подтягивает только фреймворк по пути build/xcode-frameworks/debug. Но путь для сборки фреймворка меняется, как только появляются кастомные конфигурации, и отвечает за это переменная окружения CONFIGURATION.
Тут я подумал: а зачем нам вообще разделять на разные папки для каждой конфигурации? В любом случае каждую конфигурацию мы маппим в Debug или Release build type с помощью переменной KOTLIN_FRAMEWORK_BUILD_TYPE.
Поэтому я для себя сделал следующий workaround. В Build Phase в Xcode, где собирается Kotlin-фреймворк, нужно переопределить переменную окружения конфигурации:
export CONFIGURATION=$KOTLIN_FRAMEWORK_BUILD_TYPE
cd "$SRCROOT/.."
./gradlew :shared:embedAndSignAppleFrameworkForXcode
Таким образом, для всех конфигураций, которые маппятся в Debug, всё будет работать, а для релизных конфигураций нам важнее успешная сборка, нежели подсветка кода в Xcode.
Официального ответа по этому issue я всё ещё не получил, поэтому поддержите лайком, чтобы команда JetBrains заметила и дала официальные рекомендации.
#KMP #Xcode #iOS
@kotlin_adept
Please open Telegram to view this post
VIEW IN TELEGRAM
Внезапно появилось желание адаптировать какой-нибудь KMP-проект под Аврору, и я решил узнать, как это сейчас можно сделать малой кровью. Почитал статью, посмотрел доклад, и в итоге на сегодняшний день ситуация выглядит следующим образом.
Если не брать во внимание экзотику вроде GraalVM и Kotlin Native, где нужного таргета нет почти ни в одной библиотеке, то остается только интероп через Kotlin JS и QML.
Почему-то я нигде не нашел примера с Compose для JS на Авроре. Возможно, на это есть причина, но, кажется, это наш выбор, так как почти все ключевые библиотеки поддерживают JS-таргет.
Идея очень проста: отображаем весь UI в WebView и вызываем платформенный API через колбэки с JavaScriptInterface.
За производительность, кажется, можно не переживать. По опыту, Compose в браузере работает даже быстрее, чем на iOS. Главная проблема Compose для JS — это большой бандл, но это не критично, если бандл поставляется вместе с приложением🧠
Главным камнем преткновения может стать то, что сейчас WebView в Авроре использует движок Gecko, однако в обозримом будущем планируется миграция на Chromium, и тогда все должно быть в порядке.
Очень хочется проверить эту теорию и запустить хотя бы сэмпл. Но нужного SDK под Apple-процессоры до сих пор нет в публичном доступе, так что пока ждем⌚️
#Aurora #KMP
Если не брать во внимание экзотику вроде GraalVM и Kotlin Native, где нужного таргета нет почти ни в одной библиотеке, то остается только интероп через Kotlin JS и QML.
Почему-то я нигде не нашел примера с Compose для JS на Авроре. Возможно, на это есть причина, но, кажется, это наш выбор, так как почти все ключевые библиотеки поддерживают JS-таргет.
Идея очень проста: отображаем весь UI в WebView и вызываем платформенный API через колбэки с JavaScriptInterface.
За производительность, кажется, можно не переживать. По опыту, Compose в браузере работает даже быстрее, чем на iOS. Главная проблема Compose для JS — это большой бандл, но это не критично, если бандл поставляется вместе с приложением
Главным камнем преткновения может стать то, что сейчас WebView в Авроре использует движок Gecko, однако в обозримом будущем планируется миграция на Chromium, и тогда все должно быть в порядке.
Очень хочется проверить эту теорию и запустить хотя бы сэмпл. Но нужного SDK под Apple-процессоры до сих пор нет в публичном доступе, так что пока ждем
#Aurora #KMP
Please open Telegram to view this post
VIEW IN TELEGRAM
Decompose шаг за шагом
Если вы хотели попробовать Decompose, но не знали, с чего начать, то специально для вас Максим Казанцев выпустил подробный туториал по библиотеке. Шаг за шагом автор покажет, как создать простое приложение и познакомит вас со всеми основными компонентами Decompose.
Это лишь первая часть серии видео, в которых вы подробно узнаете, как использовать Decompose на разных платформах.
Смотреть на YouTube🟥
Смотреть на VK Видео📹
#Decompose #KMP
Если вы хотели попробовать Decompose, но не знали, с чего начать, то специально для вас Максим Казанцев выпустил подробный туториал по библиотеке. Шаг за шагом автор покажет, как создать простое приложение и познакомит вас со всеми основными компонентами Decompose.
Это лишь первая часть серии видео, в которых вы подробно узнаете, как использовать Decompose на разных платформах.
Смотреть на YouTube
Смотреть на VK Видео
#Decompose #KMP
Please open Telegram to view this post
VIEW IN TELEGRAM
Представим, что вы хотите реализовать список сессий конференции и разделить их по дате. Кажется, что реализация такой UI-модели будет довольно удачной идеей:
В Android это будет работать отлично, так как функция mapOf создает LinkedHashMap, который сохраняет порядок вставки элементов. И на самом деле все будет точно так же работать, если в iOS используется Compose Multiplatform. Однако если UI будет нативным на каждой платформе, то вы столкнетесь с проблемой.
При интеропе Kotlin-кода в Objective-C ваш Map превратится в NSDictionary (или Dictionary в Swift), который не гарантирует порядок вставки элементов.
Таким образом, не стоит полагаться на порядок элементов в Map, так как этот интерфейс не может гарантировать его. Предпочитайте использовать списки в UI-моделях, чтобы обеспечить одинаковое поведение на всех платформах:
Если тема отличий в поведении между платформами в KMP интересна, то ставьте реакции и сделаю еще посты по теме.
#iOS #Android #KMP
data class SessionsUiModel(
val sessionGroups: Map<String, List<Session>>
)
В Android это будет работать отлично, так как функция mapOf создает LinkedHashMap, который сохраняет порядок вставки элементов. И на самом деле все будет точно так же работать, если в iOS используется Compose Multiplatform. Однако если UI будет нативным на каждой платформе, то вы столкнетесь с проблемой.
При интеропе Kotlin-кода в Objective-C ваш Map превратится в NSDictionary (или Dictionary в Swift), который не гарантирует порядок вставки элементов.
Таким образом, не стоит полагаться на порядок элементов в Map, так как этот интерфейс не может гарантировать его. Предпочитайте использовать списки в UI-моделях, чтобы обеспечить одинаковое поведение на всех платформах:
data class SessionsUiModel(
val sessions: List<SessionItem>
)
sealed interface SessionItem {
data class Header(val header: String) : SessionItem
data class Item(val session: Session) : SessionItem
}
Если тема отличий в поведении между платформами в KMP интересна, то ставьте реакции и сделаю еще посты по теме.
#iOS #Android #KMP
Расскажу еще об одном интересном кейсе, который выстрелил у нас при работе с KMP. И здесь удар в спину пришел откуда не ждали — убийцей оказался SQLite 🔫
Мы используем библиотеку SQLDelight для работы с БД на Android и iOS, и в одном из приложений был реализован обычный поиск через оператор LIKE. По спецификации этот оператор является регистронезависимым для ASCII-символов, но не для символов Юникода. Например, символ æ не будет равен Æ.
Так вот, на Android все работает отлично — можно искать слова в разном регистре как на латинице, так и на кириллице. А на iOS для кириллицы регистр должен точно совпадать. При этом на iOS аналогично не работают для кириллицы другие SQL-фичи, вроде COLLATE NOCASE или функции LOWER. На этот счет в SQLDelight есть соответствующий issue.
Поэтому нам пришлось явно сохранять в БД информацию в нижнем регистре и приводить строку поиска к нижнему регистру, чтобы поиск работал корректно на обеих платформах.
Так что, если соберетесь делать локальный поиск в БД, помните об этом нюансе и не наступайте на наши грабли❤️
#KMP #SQL #iOS
Мы используем библиотеку SQLDelight для работы с БД на Android и iOS, и в одном из приложений был реализован обычный поиск через оператор LIKE. По спецификации этот оператор является регистронезависимым для ASCII-символов, но не для символов Юникода. Например, символ æ не будет равен Æ.
Так вот, на Android все работает отлично — можно искать слова в разном регистре как на латинице, так и на кириллице. А на iOS для кириллицы регистр должен точно совпадать. При этом на iOS аналогично не работают для кириллицы другие SQL-фичи, вроде COLLATE NOCASE или функции LOWER. На этот счет в SQLDelight есть соответствующий issue.
Поэтому нам пришлось явно сохранять в БД информацию в нижнем регистре и приводить строку поиска к нижнему регистру, чтобы поиск работал корректно на обеих платформах.
Так что, если соберетесь делать локальный поиск в БД, помните об этом нюансе и не наступайте на наши грабли
#KMP #SQL #iOS
Please open Telegram to view this post
VIEW IN TELEGRAM
Зачем мигрировать на котлиновский UUID?
Вы, наверное, слышали, что в Kotlin появился встроенный генератор UUID, который можно использовать в общем коде. Но он всё ещё экспериментальный, да и вообще написать expect/actual функцию можно в одну строчку. Поэтому, думаю, многие даже и не задумывались о переходе в KMP-проектах. Но на самом деле это имеет смысл.
Проблема с подходом expect/actual заключается в том, что UUID под iOS будет генерироваться в верхнем регистре, и это может привести к проблемам. Например:
Представим, что вы работаете с чатом и сохраняете какое-то сообщение с неким ID в БД и отправляете его же на сервер. Но при следующей загрузке данных с бэкенда вам возвращается это сообщение с ID в нижнем регистре. Если вы использовали обычный SQL-запрос для поиска сообщения по ID, то ничего не найдёте, потому что регистр отличается. В то время как на Android всё будет работать корректно.
Таким образом, использование нового механизма генерации поможет избежать этой проблемы, так как UUID будет генерироваться в одном виде на всех платформах. Помимо этого вы получаете лучшую типобезопасность, так как можете вместо String использовать Uuid для всех идентификаторов в вашем коде.
#KMP #Kotlin
Вы, наверное, слышали, что в Kotlin появился встроенный генератор UUID, который можно использовать в общем коде. Но он всё ещё экспериментальный, да и вообще написать expect/actual функцию можно в одну строчку. Поэтому, думаю, многие даже и не задумывались о переходе в KMP-проектах. Но на самом деле это имеет смысл.
Проблема с подходом expect/actual заключается в том, что UUID под iOS будет генерироваться в верхнем регистре, и это может привести к проблемам. Например:
Представим, что вы работаете с чатом и сохраняете какое-то сообщение с неким ID в БД и отправляете его же на сервер. Но при следующей загрузке данных с бэкенда вам возвращается это сообщение с ID в нижнем регистре. Если вы использовали обычный SQL-запрос для поиска сообщения по ID, то ничего не найдёте, потому что регистр отличается. В то время как на Android всё будет работать корректно.
Таким образом, использование нового механизма генерации поможет избежать этой проблемы, так как UUID будет генерироваться в одном виде на всех платформах. Помимо этого вы получаете лучшую типобезопасность, так как можете вместо String использовать Uuid для всех идентификаторов в вашем коде.
#KMP #Kotlin
Фоновая работа в Android и iOS
Бытует мнение, что iOS вообще не позволяет приложению выполнять какие-либо действия в фоне, но это не совсем так. В одном из наших Compose Multiplatform приложений необходимо было реализовать синхронизацию данных в фоне, и моему коллеге пришлось глубже разобраться в теме.
➖ На текущий момент не существует хорошего решения для KMP-проектов, которое предоставляло бы общий API для работы с фоновыми задачами. Это вполне объяснимо: API сильно отличаются между платформами.
🤖 Для решения задачи синхронизации данных в фоне в Android существует несколько решений, например, WorkManager, который имеет довольно удобный API и позволяет запускать задачи с интервалом не менее 15 минут. Он позволяет задать условия запуска задачи, порядок выполнения воркеров и определить поведение при повторном планировании одной и той же задачи.
🍏 В iOS есть два стула: BGAppRefreshTaskRequest и BGProcessingTaskRequest.
Первый предназначен для относительно быстрых операций длительностью до 30 секунд и может выполняться чаще, второй — для более долгих задач, которые могут выполняться в течение нескольких минут и даже часов. Разумеется, можно указать минимальное время, через которое должна быть выполнена синхронизация. В интернетах рекомендуют устанавливать интервал в один час, однако iOS конечно же не гарантирует, что задача будет выполнена вообще🙃
С появлением SwiftUI стало удобнее работать с фоновыми задачами — достаточно запланировать их с помощью BGTaskScheduler и обрабатывать через модификатор backgroundTask. Однако, по сравнению с WorkManager, многое приходится делать вручную — например, явно обрабатывать ситуацию, когда задача уже запланирована, иначе интервал её запуска может быть сброшен.
📌 Таким образом, реализовать фоновую работу в мультиплатформенных проектах вполне возможно, но для этого потребуется написать платформенный код.
#iOS #Android #Background #KMP
Бытует мнение, что iOS вообще не позволяет приложению выполнять какие-либо действия в фоне, но это не совсем так. В одном из наших Compose Multiplatform приложений необходимо было реализовать синхронизацию данных в фоне, и моему коллеге пришлось глубже разобраться в теме.
Первый предназначен для относительно быстрых операций длительностью до 30 секунд и может выполняться чаще, второй — для более долгих задач, которые могут выполняться в течение нескольких минут и даже часов. Разумеется, можно указать минимальное время, через которое должна быть выполнена синхронизация. В интернетах рекомендуют устанавливать интервал в один час, однако iOS конечно же не гарантирует, что задача будет выполнена вообще
С появлением SwiftUI стало удобнее работать с фоновыми задачами — достаточно запланировать их с помощью BGTaskScheduler и обрабатывать через модификатор backgroundTask. Однако, по сравнению с WorkManager, многое приходится делать вручную — например, явно обрабатывать ситуацию, когда задача уже запланирована, иначе интервал её запуска может быть сброшен.
#iOS #Android #Background #KMP
Please open Telegram to view this post
VIEW IN TELEGRAM