Обновить

Мобильная разработка

Сначала показывать
Порог рейтинга
Уровень сложности

Error messages in UX: how to make them effective and user-friendly

Уровень сложностиПростой
Время на прочтение5 мин
Охват и читатели7.5K

An error message is a short message that appears on the screen when a user does something wrong or a software product itself fails to perform and complete a certain action. They are often perceived as insignificant annoying notifications that no one actually reads before clicking “OK”, but in fact they play a vital role in providing information on any problems and issues that users encounter during app use and aiding them in completing tasks successfully. The way error messages are designed impacts user experience heavily: poor design leaves users in confusion on what exactly went wrong and how to fix it, which in its turn leads to frustration and even app abandonment, whereas effectively crafted messages serve as a helpful tool in providing clarity on how to proceed when encountering an issue. 

Читать далее

Миграция с Flutter Web на Jaspr: наш опыт

Время на прочтение8 мин
Охват и читатели9.2K

Уже несколько лет мы занимаемся развитием клиентского приложения на Flutter: начинали с мобильных платформ, когда веб и десктоп вышли в бету – портировали его и на эти платформы. Последние два года PWA крутится в проде и в некоторых регионах является самой популярной платформой для нашего приложения.

Недавно мы попробовали мигрировать наше приложение с Flutter Web на Jaspr – под катом расскажем о том, почему мы это сделали, с какими трудностями столкнулись и какие выводы сделали.

Да кто такой этот Jaspr?!

Мне надоело писать один и тот же код. Поэтому я сделал Featuregen

Уровень сложностиСредний
Время на прочтение6 мин
Охват и читатели18K

Привет, Хабр. Я уже не тот беззаботный парнишка, что собирал 486-й компьютер. Время бежит, я скуф успел поработать с C++, C#, Java и Kotlin, последние 10 лет занимаюсь мобильной разработкой. Программирование я до сих пор люблю потому что больше ничего не умею. Но чем дольше работаешь, тем чаще ловишь себя на мысли, что от некоторых вещей начинает подгорать. Сегодня я расскажу, как я попытался избавиться хотя бы от части таких вещей.

Читать далее

Как мы съездили в Японию и запустили Пополаму — сервис, который знает кто кому должен

Уровень сложностиПростой
Время на прочтение4 мин
Охват и читатели14K

Перед совместной поездкой всегда кажется, что главные вопросы — это билеты, жильё и маршрут. Но если вы едете компанией, есть ещё один вопрос, который почти всегда всплывает уже по ходу дела и особенно по окончании поездки: кто кому и сколько должен?

Более года назад мы готовились к поездке в Японию 🇯🇵. Нас было 6 человек и встал логичный вопрос: в чем будем вести учет общих расходов? Казалось бы, в 2024–2025 годах это давно решенная проблема, но на практике всё оказалось максимально неудобно, а делить на всех было бы не очень честно — кто‑то платил за отель, кто то за такси, другой постоянно закрывал счет в барах, хотя брал там только салат и так далее

Поездка в Японию и давняя идея сделать продукт для деления расходов сподвигли нас запустить Popolama — сервис про людей и деньги.

Читать далее

Как ускорить проверку приложения с помощью Impact-анализа. Часть 3: UI-тесты

Уровень сложностиСредний
Время на прочтение4 мин
Охват и читатели4.3K

Когда проект растёт, дольше всего начинают тянуться самые «тяжёлые» проверки – UI-тесты. Один-два модуля поменял, а CI всё равно гоняет сотни тестов на эмуляторах и ждёт их десятки, а то и сотни минут. Знакомо?

Это третья, финальная статья цикла о том, как мы в Циане перешли от полного прогона всех проверок к выборочному с помощью Impact-анализа. В первой части я показывал, как мы ускорили статические анализаторы, во второй — как в два раза сократили unit-тесты, научившись обходить граф Gradle-модулей. В заключительной части я расскажу, как у нас на проде реализован выборочный запуск UI-тестов.

Читать далее

Лучшая архитектура KMP-приложений и когда её не использовать. Часть 1

Уровень сложностиСредний
Время на прочтение12 мин
Охват и читатели4.4K

В архитектуре KMP+CMP-приложений главный вопрос не в том, сколько кода можно пошарить. Он в том, где нужно остановиться.

Я покажу два рабочих подхода. Первый — архитектура для большого мобильного продукта: общий Kotlin-слой для бизнес-логики и нативный UI на каждой платформе. Второй — стартаповый путь, где Compose Multiplatform помогает быстро запустить мобильные продукты, web- и desktop-приложения. И даже backend на общих моделях данных.

Поговорим о том, когда нужно и не нужно применять «лучшую» архитектуру.

Читать далее

Plumix: как я переписываю Flutter на C# — вместе с ИИ

Уровень сложностиПростой
Время на прочтение8 мин
Охват и читатели8.8K

Я скучал по C#, когда писал на Flutter, и по Flutter — когда писал на C#. Поэтому взял и совместил: Plumix — фреймворк с флаттеровской архитектурой виджетов поверх .NET и Avalonia, который во многом строят ИИ-агенты. Рассказываю про мотивацию, конвейер портирования, текущие фичи и планы.

Смотреть, что получилось

Тренажер Юмора — приложения для обучения шуткам

Уровень сложностиПростой
Время на прочтение2 мин
Охват и читатели10K

В юморе существуют паттерны шуток которыми пользуются все комики и все люди которые когда либо шутили. Они уже давно известны. Перечень паттернов

Подмена ожидания, Гипербола, Сравнение, Ирония, Сарказм, Двусмысленность, Каламбур, Абсурд, Антишутка, Шутка с вопросом-ответом, Повтор с нарастанием, Ложная логика, Доведение до абсурда, Обратный смысл, Нелепица, Пародия, Цитата вне контекста, Чёрный юмор, Самоирония, Эскалация

И я решил написать программу тренажер для тех кто хочет научиться остроумно шутить.

Читать далее

Swift 6.2 против вашего оптимизатора: разбираемся с InlineArray, Span и strict memory safety на замерах

Уровень сложностиСредний
Время на прочтение17 мин
Охват и читатели7.6K

Про ARC, weak/unowned и retain cycle на русском написано столько, что добавить нечего. Про borrowing/consuming и ~Copyable (это, к слову, Swift 5.9, а не 6 - частая путаница) на английском тоже десятки разборов. И почти все они устроены одинаково: объясняют, что фича делает, на игрушечном примере с файловым дескриптором, и заканчивают выводом «так безопаснее и быстрее».

Мне захотелось зайти иначе. Я взял три «памятных» нововведения Swift 6.2, написал на них бенчмарки, прогнал на релизном тулчейне и полез в сгенерированный ассемблер. Вопрос меня занимал не «что это делает», а куда более практичный: дают ли эти фичи реальный выигрыш в цифрах - и в каких случаях оптимизатор Swift давно делает то же самое за вас, бесплатно и молча. Ответ оказался менее очевидным, чем их маркетинг.

Статью я старался написать так, чтобы её читал не только стафф. Поэтому по ходу я коротко объясняю базовые вещи - стек и кучу, ARC, copy-on-write. Если вы это и так знаете, просто пролистывайте врезки «на полях».

Читать далее

Пишем мобильную ОС на Rust. Часть 3. Путь от bare-metal эксперимента к capability-based микроядру

Уровень сложностиСредний
Время на прочтение18 мин
Охват и читатели11K

В первой части мы загрузили своё ядро на настоящий телефон, вывели «Hello world» в UART и нарисовали квадратик на экране. Во второй — научили ядро управлять памятью и завели кучу.

С тех пор прошло более 4 месяцев, и проект тихо перешагнул важную черту: из bare-metal эксперимента получилось микроядро. В привилегированном режиме остались только процессы, память и передача сообщений, а всё остальное — драйверы, сервисы, будущая графика — обычные программы снаружи. Само ядро при этом выросло с неполной тысячи строк до сорока пяти тысяч.

В этой статье разберёмся, что такое capability и handle и при чём здесь seL4 и Zircon, запустим свой процесс-"калькулятор" на телефоне и поговорим с ним по IPC, а под конец напишем userspace-драйвер часов для устройства, про которое в ядре нет ни строчки.

Получить хэндл на статью

Как сломать Swift Concurrency

Уровень сложностиСредний
Время на прочтение6 мин
Охват и читатели13K

Нужно выполнять асинхронные операции, поддерживать многозадачность в приложении? Async/await к вашим услугам - просто и приятно. Кооперативный пул эффективно переключает потоки между задачами, а компилятор проверяет типы на потокобезопасность. И даже можно подсоединять старые части кода, написанные ещё на GCD!

Вот только приложение на проде почему-то начало виснуть…

Читать далее

Мобильная разработка за неделю #637 (29 июня — 5 июля)

Уровень сложностиПростой
Время на прочтение5 мин
Охват и читатели9.4K

В новом дайджесте UISlider изнутри и навигация в Jetpack Compose без магии, миграция приложения на Navigation 3 и сборщик мусора в Dart, мобильное тестирование в 2026, как меняется разработка в эпоху ИИ, новые модели Anthropic и Google и многое другое. Заходите!

Читать далее

UISlider изнутри: почему `setValue` не работает во время settle-анимации и как я это обошел

Уровень сложностиСложный
Время на прочтение11 мин
Охват и читатели7K

В iOS 26 у UISlider появился liquid-glass-вид и физика доводки (settle) после того, как пользователь отпускает палец. Если честно, я не проверял, как это выглядело в старых версиях и как оно работало, так как до iOS 26 ни в своих проектах, ни в тех, что я писал на работе, я не использовал стандартный компонент, так как его внешний вид никого не устраивал. У такой доводки есть побочный эффект: если в этот момент дернуть setValue(_:animated:) извне, наш слайдер на один кадр едет в новую точку, а потом откатывается туда, куда его тянет settle. removeAllAnimations() не помогает: анимация идёт не через CABasicAnimation, а через property-driver на display link. Дальше про то, как я нашёл рабочий путь это исправить.

Читать далее

Ближайшие события

Словари MDict в закрытом приложении, или зачем я писал RIPEMD-128 вручную

Уровень сложностиСредний
Время на прочтение4 мин
Охват и читатели10K

Добавлял в свою читалку офлайн-словари и упёрся в MDX, формат словарей MDict. Проприетарный, официальной спеки от создателей нет. Готовые Java-парсеры под GPL, а у меня закрытое приложение, тащить нельзя. Значит, пишу свой, с нуля и без зависимостей. Рассказываю, как формат устроен внутри, где я споткнулся, и почему пришлось руками писать RIPEMD-128, чтобы прочитать даже оглавление словаря.

Читать далее

Почему Android экран дёргается: простые ошибки, которые ломают плавность

Уровень сложностиСредний
Время на прочтение12 мин
Охват и читатели6K

После этой статьи вы сможете найти самые частые причины лагов в Compose-экранах и быстро убрать их без больших переписываний.

Разберем, почему большие экраны начинают дергаться, как lazy-списки ломаются из-за плохих ключей, где тяжелая работа незаметно попадает в UI-поток и какие правки обычно дают самый быстрый эффект.

Хочу читать дальше

Как я стал туалетным сомелье

Уровень сложностиПростой
Время на прочтение4 мин
Охват и читатели18K

История о том, как я стал туалетным сомелье Минска и создал карту всех местных уборных с расписанием, рейтингом и компасом.

Читать далее

Сборщик мусора в Dart. Часть 1: память и указатели

Уровень сложностиСредний
Время на прочтение6 мин
Охват и читатели7.8K


Про сборщик мусора сейчас почти не говорят, но я часто слышу от коллег, что на собеседованиях про него спрашивают. Ещё заметил, что это один из популярных вопросов. Нормальных статей или обзоров про это почти нет, а если и есть, то они тяжёлые и очень нагруженные технической частью, которую понимают только сами создатели статей.

Эта статья – моя попытка объяснить вам доходчивым языком, что же такое Garbage Collector в Dart, объяснить почему эти некоторые знания нам нужны на практике и что из всей этой тяжелой, технической внутрянки вам необходимо знать.

Читать далее

Как энергосбережение на Android мешало Seamless-авторизации

Уровень сложностиСредний
Время на прочтение10 мин
Охват и читатели7.9K

Всем привет! Я Никита, тимлид команды Android в Банки.ру. 

Недавно, внедряя в приложение фичу авторизации без SMS-кода (seamless), мы столкнулись с тем, что она в упор отказывалась работать – но только на Android. Мы дебажили ее полторы недели, перепробовали все возможные варианты и закошмарили всех доступных операторов связи, прежде чем узнали, что все дело было… в энергосбережении.

В статье рассказал про наш путь борьбы с энергосбережением и, возможно, это сэкономит вам десятки часов дебага.

Читать далее

Как врач на пенсии создал AI‑приложение для определения биологического возраста на Flutter + TFLite

Уровень сложностиПростой
Время на прочтение10 мин
Охват и читатели6.4K

Я врач с более чем 30-летним стажем, последнее время работал доцентом медицинского вуза. Недавно вышел на пенсию и получил то, о чем мечтал всю трудовую жизнь — много свободного времени, и часть его желательно тратить с пользой (а не только играть на ПК, что я, конечно, тоже люблю).

Я давно, со студенчества, интересовался проблемами старения организма. Поработав с десятками тысяч пациентов, я уже не удивлялся, что паспортный (хронологический) возраст и реальное состояние организма — это две разные вещи. Один пациент в 60 бегает марафоны, другой в 45 еле ходит по дому. Но причины этого медицине, честно говоря, до ситх пор непонятны. Мне хотелось как‑то объективизировать, оцифровать, что ли, эту разницу без сложных анализов и дорогостоящих исследований. И чтобы каждый человек мог легко и просто оценить свой биологический возраст — не просто для того, чтобы его узнать — а сделать определенные выводы и, возможно, изменить свои привычки и даже обратиться к специалистам. Теперь для этого есть общедоступные инструменты — смартфоны с фотокамерой, искусственный интеллект и модели, способные анализировать, состояние кожи и другие показатели по фотографии. Надо попробовать, решил я. Но для этого нужно создать мобильное приложение. Раньше я бы на такое не замахнулся, ну а сейчас — время есть, инструменты есть, желание есть — why not?

Читать далее

Навигация в Jetpack Compose без магии: что на самом деле делают библиотеки навигации

Уровень сложностиСредний
Время на прочтение18 мин
Охват и читатели6.9K

Вы когда-нибудь задумывались, зачем нужны библиотеки для навигации в Jetpack Compose? Почему мы не можем просто взять mutableStateOf со списком экранов и переключаться между ними? Оказывается, если мы попробуем реализовать такой наивный подход, то столкнёмся с рядом проблем: rememberSaveable не работает, ViewModel не очищаются после ухода с экрана, Lifecycle не работает корректно и многое другое.

В статье разберём, как работают библиотеки навигации в Jetpack Compose и какие задачи они решают на примере библиотеки навигации Modo.

Читать далее