Android & Coffee с Васей
183 subscribers
74 photos
5 videos
50 links
Канал для разговоров за кофе о разработке. В основном Android, но вообще как получится
Download Telegram
Открытие прошло... довольно гладко!

Хотя и не без сюрпризов:
- нашли несколько визуальных косяков в андроиде
- "редкие" кейсы на бэке — всплыли сразу же
- Terms & Conditions в виде PDF не открывался в WebView
- самая важная ошибка — на скрине :D

Итак, открыли аккаунт, выдохнули, приготовились праздновать. Переходим на главный экран, и
🔥2
...ошибка. Оказалось, что мы не договорились, и параллельно с тестированием зарелизили новый контракт с ломающими изменениями. К тому же, изменения были во второстепенном запросе. Итак:
- правим контракт
- добавляем деградацию с фолбэком (не отображаем не загрузившийся блок)
- быстро релизим обновление

В этот раз всё сработало! Увидели главный экран и баланс 0.00.

ПЕРВЫЙ АККАУНТ JAZARI ОТКРЫТ! ❤️‍🔥
🔥3🫡1
И не просто открыт — мы получили первое пополнение с Revolut и перевели реальные деньги на аккаунт в Monzo. Перевели.РЕАЛЬНЫЕ.ДЕНЬГИ.

Всё прошло отлично. Не без косяков, но намного лучше, чем я ожидал от первого боевого запуска.
🔥🔥🔥
🔥5
Больше почитать можно в каналах других участников нашей команды:

- 99developers — канал Саши Андронова, нашего CTO. Сейчас пишет про стартап
- Рубанов про мобилу — канал Миши Рубанова. Много про iOS разработку и мобильную разработку вообще
1
Kotlin Guard Conditions

В Kotlin 2.1.0 появилась экспериментальная фича, которая по умолчанию выключена — guard conditions в when.

Теперь можно писать дополнительные условия прямо в ветках when, не теряя преимущества exhaustiveness. Пример можно увидеть на скриншоте.

Раньше приходилось:
— либо писать вложенные if'ы внутри ветки
— либо использовать when без аргумента (и терять исчерпывающую проверку)

Теперь можно писать короче, чище и при этом получать ошибки компиляции, если забыли обработать кейс.

Важно помнить, что, как у любой конструкции языка, у guard condition есть своя область применения. Иногда лучше написать вложенный if (например, для читаемости или для выполнения рефакторинга). Нужно смотреть по ситуации.

❗️ Фича экспериментальная. Сейчас чтобы включить фичу нужно прописать специальный флаг для компилятора:

android {
...

kotlinOptions {
freeCompilerArgs = listOf("-XXLanguage:+WhenGuards")
}
}


💭 А вы уже включили guard condition?
🔥4
Instant и Clock — deprecated

Если вы обновите kotlinx-datetime до версии 0.7.0, проект, скорее всего, перестанет собираться.
Исчезают kotlinx.datetime.Instant и kotlinx.datetime.Clock.

😱 WUUUT?

Разработчики сжалились и выпустили 0.7.1, где временно добавили typealias'ы для обратной совместимости.

Что происходит?

Начиная с Kotlin 2.1 типы Instant и Clock официально переезжают в стандартную библиотеку — в пакет kotlin.time.
Вот ссылки на новые версии:
🔗 Instant
🔗 Clock
📦 Миграция на kotlinx-datetime 0.7.1 — что нужно знать

Если используете kotlinx-datetime, просто обновитесь до 0.7.1. Всё должно работать, если:
— у вас нет зависимостей от библиотек, которые требуют старую версию kotlinx-datetime
— вы не сериализуете Instant через kotlinx-serialization (если да — обновитесь до 1.9.0+)

Если после обновления ловите ClassNotFoundException на Instant или Clock, значит какая-то библиотека ещё не обновилась.

🔧 В этом случае можно временно использовать совместимую версию:
0.7.1-0.6.x-compat — она содержит старые классы для обратной совместимости.
Но лучше использовать только в крайнем случае.

Более подробно о миграции можно прочитать в репозитории: https://github.com/Kotlin/kotlinx-datetime?tab=readme-ov-file#deprecation-of-instant
Сделать 99.78.dp или 100.dp? 🤪
😁7
Технологическая крыса — пока команда тащит релиз, он пробует новый фреймворк
🤣4
Говоря о технологических крысах... я только что попробовал новый фреймворк 😅

🎛 Flocon — инструмент, о котором недавно писал Кирилл Розов у себя в канале. Хочу поделиться впечатлениями — кажется, штука действительно заслуживает внимания.

Я вообще люблю всякие утилиты, которые упрощают разработку. В частности, мне всегда нравился Flipper от Facebook. Судя по всему, я не один такой — вот буквально только что Максим Качинкин писал об этом же у себя (кстати, если ещё не подписаны — советую: https://t.me/mobilefiction).

Поэтому я не мог обойти стороной инструмент, который:
- внешне очень похож на Flipper
- сам автор пишет, что он inspired by Flipper
- написан на Kotlin Multiplatform + Compose Multiplatform

💥 Решил сразу с ноги интегрировать Flocon в Jazari.

Что пошло так, а что не очень — расскажу в следующем посте 👀
👍5
🚀 Flocon — первый взгляд

Итак, попробовал новый инструмент Flocon — аналог Flipper, но на KMP + Compose Multiplatform. Делюсь первыми впечатлениями:

Плюсы:
Гибкость — реально гибче, чем Flipper
— Я пока не видел нативного кода. Если его правда нет, то поддержка 16KB страниц памяти не будет требоваться, как было с Flipper
Популярность — проекту неделя, а уже куча звёзд. Люди пробуют и им заходит
Скорость — десктопная версия на KMP работает намного быстрее, чем Flipper
Дашборды — пушка 💥
Активное развитие — автор активно ревьюит PR’ы, отвечает, обсуждает идеи

⚠️ Нюансы:

Проекту неделя — решайте сами, плюс это или минус 🙂 📅
Проблемы с изображениями — сначала показывались чёрные квадраты. Заработало после запуска dev-версии из IDE 🖼
UI десктопного клиента сыроват — не хватает базовых удобств: сортировки, закреплений, базовой навигации 🧱
Нет no-op реализации — issue есть, но автор пока не горит её делать. Чтобы не пропустить в прод лишний код, нужна хорошая модуляризация. В некоторых случаях может потребоваться переработка архитектуры — может не подойти некоторым проектам 🚫
minSdk 24 — кому-то может быть критично 📱
iOS не поддерживается и я пока не видел планов (Flipper умеет работать с iOS) 🍏
👍2
🚀 Что сделали в Jazari за последние 2 месяца

Мы наконец-то запустились.
Полноценный банковский сервис. С нуля.
До сих пор звучит как безумие 😅

По продукту:
— в июле пошли в прод. После тестовых открытий аккаунтов и переводов денег начали регистрировать реальных пользователей
— активность выше, чем ожидали: заказывают карты, делают покупки, переводят деньги, берут кредиты
— пускаем по очереди, сейчас >2000 человек. Цель на август — 5000+. Часть проверки автоматизирована, но без ручной работы пока никак, поэтому 2000 — хороший результат

Запуск прошел довольно удачно. По приложениям и апи был минимум нареканий, в основном не учли редкие кейсы.

❗️На запуске оказалось, что мы плохо обучаем пользователя на входе, из-за чего в саппорт прилетает много однотипных вопросов
🔥4
🐛 Самое серьёзное, что прилетело — на ошибки загрузки данных мы показывали Ooops экран. Он попадался часто и создавал ощущение, что с приложением всё очень и очень плохо. Дошло до того, что CTO ввёл мораторий на Ooops экран 😁

Экран пока не убрали, но стали показывать реже, добавили ретраи, стабилизировали поведение. Пользовательский опыт стал значимо лучше.
👍3😁1
📱 Что нового в Jazari

— При регистрации выяснилось: у многих нет паспорта под рукой, зато есть права. Теперь принимаем водительское удостоверение 🚗

— Запустили предзаказ лимитированной карты (на скрине). Пока без рекламы. Видео и анимация — покажу отдельно

— Ввели кэшбэк с ревордами с Waitlist. Для многих это главный мотиватор зарегистрироваться. До этого часть людей закрывала аккаунты из-за отсутствия бонуса 💰

— Главный экран — переделали уже дважды 🤔
— Экран перевода денег — трижды 🤯

— С кредитами: хотят многие, но разрешено меньше, чем планировали. Тем, кому нельзя, пробуем аккуратно объяснять причину — уже 3 варианта UX, и продолжаем улучшать 💸

— Новая кредитная программа — можно брать кредит даже без своих денег на счету. Пользуются активно 💸

— Много потенциальных фродеров — часть аккаунтов закрыли 🕵️‍♀️

— Некоторые сами закрывают аккаунты. Теперь собираем причины и рассказываем о будущих улучшениях. Иногда помогает оставить пользователя. 🛑
👍1
🛠 Технические обновления

— Полностью переделали систему аналитики: добавлять события теперь супер просто, вся документация в одном месте, Android и iOS синхронизированы 📊

— Для отладки (только дев-версии) добавили:
 • Chucker
 • Flocon
 • Шеринг логов устройства прямо из приложения
 • для Flocon понадобилась модуляризация. Очень хотел это отложить, но не вышло. Сделал по аналогии с Now In Android — крупные утилитарные модули, крупные модули фич (пока без деления на апи/реализацию, но скоро тоже придётся делать) и app-модули

— Ещё раз прикрутили libphonenumber — расскажу отдельно ☎️

— Часть логики билда вынесли в Convention Plugins — стало проще поддерживать build.gradle и добавлять модули ⚙️

— В приложении много Bottom Sheet, поэтому сделали своё API поверх Material — получилось удобно, думаю рассказать 📱
👍5
Forwarded from 99developers (Alex Andronov)
С апдейтами для вас.

- включили международные переводы. С такими рейтами что хрен с нами кто поконкурирует. Пока не промоутим.
- запустили 1% кэшбека всем кто рефералил в вейтлисте. Им оставим все это на постоянке.
- 2,500 транзактящих пользователей. Конверсия от активного аккаунта в транзактящего пользователя больше 65%, неплохо.
- отладили ревью и комплаенс.
- кредиты растут так что к четвергу мы обычно перекрываем результат прошлой недели. Выплаты пока в норме, просрочки есть, но их оч мало.
- выключил вейтлист, получил леща от Миши, включил вейтлист обратно.
- встроили AI агента в чат в админке.
- начали делать SMM AI агента. Идея чтобы было дофига AI сотрудников живет и развивается.
🔥2
🚀 Firebase Real-Time Remote Config

С Firebase можно получать оповещения об изменении Remote Config.

Без real-time оставалось два варианта:
— ждать N часов для обновления
— дёргать fetch слишком часто и упираться в квоту 😵‍💫

Real-Time Remote Config позволяет запрашивать конфиг ровно тогда, когда он реально поменялся.

Как это устроено:
— клиент держит соединение с сервером Real-time Remote Config
— сервер шлёт сигнал об инвалидации
— клиент сам вызывает fetch (но не activate — важно)

Дальше решаете сами: применять сразу, вызвав activate, или, например, только при следующем старте.

⚙️ Чтобы включить real-time, нужно:
— в GCP включить Firebase Remote Config Realtime API (иначе listener молчит)
— добавить addOnConfigUpdateListener

Выглядит магически: меняешь флаг в консоли → приложение само узнаёт и реагирует.
👍1😢1
Подводные камни Firebase Real-Time Remote Config

Вот детали, о которых нужно помнить:

1️⃣ Нет гарантии доставки. Соединение с сервером может не установиться или разорваться. Вроде SDK обрабатывает это, но на практике обновления иногда «теряются»

2️⃣ Долгоживущее HTTP-соединение → дополнительный расход батареи и ресурсы

3️⃣ Нужно продумать активацию. Иначе рискуете: приложение стартовало в одном состоянии, а внезапно переключилось в другое

4️⃣ Конфиг может обновиться, пока приложение закрыто. Тогда апдейт дойдёт только через несколько секунд после старта. Если не вызвать activate сразу — изменения попадут лишь на следующем запуске. Иногда это ок, иногда критично
👍1
Во-первых, это красиво 😂
😁10🫡4
💁‍♂️ На техдолг можно забить
.
.
.
если любите запах горящего прода по утрам


Одно утро началось с "у нас жопка с Intercom" от CTO. Пользователи в поддержке видят чужие сообщения.
Нашли статью, собрались консилиумом. Я читаю — и понимаю: накосячил я.

Хронология фиаско:
— очень давно завёл Account с id "на будущее", оставил TODO (на скрине). Тогда бэк еще не присылал id, поэтому оставил так;
— позже добавил чтение id из JWT, но не для Account;
— когда понадобилось использовать id, в одном месте взял его из JWT, а в другом — из Account.

Бомба взорвалась, когда пользователи с одинаковым именем пришли в саппорт.
Хотфикснули, почистили пользователей.

Вывод: техдолг обычно не взрывается сразу. Он копится и стреляет в самый неожиданный момент. Не копите техдолг.
👍6😱1
🪛 Архитектура Android-приложений

На Хабре и в других блогах регулярно выходят статьи про архитектуру Android приложений. Особенно часто — про устройство presentation слоя: вью, вью модель, немного затрагивают домен, почти никогда внешние зависимости.

Это любопытно: несмотря на официальные рекомендации Google, сообщество продолжает искать свои решения.

Почему?

Гайдлайны от Google (как и любые другие) дают каркас, но в реальных проектах остаётся много открытых вопросов. Их сложно закрыть одним рецептом: разные ожидания от продукта, окружение, требования по безопасности и UX часто конфликтуют — отсюда новые компромиссные подходы.

Если сказать кратко, любое «плохое» решение в проекте можно оправдать его эволюцией 😆

Пара интересных статей последних месяцев:
Compose + Koin + Jetpack Navigation: что мы поняли за 2 года
Демоприложения: как жить, когда у вас 90+ application-модулей
Разбираем чистую архитектуру в Android: от а до я
Функциональное программирование в Android. Побочные эффекты и ELM-архитектура
Архитектура Android. Понятно и подробно
👍4