Обновить

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

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

Меняем Punto Switcher на macOS: открытый код, ноль телеметрии и ноль зависимостей — в обоих смыслах

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

Если серьёзно — зависимостей у RuSwitcher действительно ноль: только системные фреймворки и чистый Swift, никакой телеметрии и ничего постороннего в Package.swift. Но начнём с боли.

Если вы пишете на двух языках, то знаете эту боль: набрал полстроки, поднял глаза — а там ghbdtn вместо «привет». На Windows эту проблему закрывает Punto Switcher. А на macOS? Его Mac‑версию Яндекс забросил ещё в 2017-м, да и у самого Punto хватает «сюрпризов»: встроенный кейлоггер‑«дневник», телеметрия, навязывание Яндекс‑сервисов и закрытый код. Мне хотелось простого, открытого и без слежки — поэтому я написал своё: RuSwitcher, лёгкий переключатель раскладки в меню‑баре. Open source (MIT), ноль зависимостей, ноль телеметрии.

В статье — как это устроено внутри: перехват клавиатуры через CGEventTap, динамический маппинг любых двух раскладок через UCKeyTranslate, и отдельно — раздел «грабли», включая историю про то, как я случайно выложил релиз, где DMG назывался 2.1.0, а внутри лежала сборка 2.0.3.

Втянуться без зависимостей

Nostr — бэкенд «из коробки»: где подходит, а где нет

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

Готовый децентрализованный бэкенд без своего сервера — звучит заманчиво. На личном опыте двух приложений разбираю, где Nostr реально экономит месяцы работы, а где упирается в одно базовое ограничение и начинает мешать: заметки, чаты, ленты, communities, организации.

Читать далее

Backend-Driven UI для умного дома: как обучить сервер верстать интерфейсы

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

Привет, Хабр! 

Я Дмитрий, iOS-разработчик из команды Салют — мы делаем устройства и программное обеспечение для Умного дома Сбер. У нас много собственных устройств и ещё больше устройств брендов-партнёров, которые поддерживает платформа. Релизный круговорот фичей и интеграций заставляет думать: как оптимизировать процесс доставки новых функций пользователям?

В статье расскажу про опыт разработки, внедрения и поддержки нашей собственной backend-driven UI парадигмы (BDUI) — подхода, в котором сервер управляет не только данными, но и вёрсткой интерфейсов.

Читать далее

Бесплатное lo-fi радио + живые обои на рабочий стол: собрал десктоп-приложение на Tauri 2 (форк lofi-engine)

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

Я хотел одну простую вещь: чтобы на втором мониторе тихо играло lo-fi, а за виджетами крутилась уютная анимированная сцена. Готового решения не нашлось — зато нашёлся чужой MIT-проект, у которого я в итоге выкинул главный модуль и собрал из остатков совсем другой продукт. Это девлог о том, что я удалил, что добавил и на каких граблях потанцевал.

Под задачу подходящих инструментов хватало, но каждый закрывал только часть. Wallpaper Engine — живые обои, но без радио. Lofi.co — музыка в браузере, но не обои рабочего стола. Noisli — эмбиент, но без всего остального. Покупать три подписки ради фона под код было жалко, поэтому я полез на GitHub смотреть, что можно собрать самому.

Нашёл meel-hd/lofi-engine под MIT — аккуратный Tauri-проект со встроенным генеративным движком, который синтезировал lo-fi прямо в браузерном рантайме. Идея красивая, но мне быстро стало понятно, что я хочу совсем другого продукта. Так появился форк, который я в итоге назвал LoFiTyan.

Читать далее

Мобильная разработка за неделю #635 (15 — 21 июня)

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

В новом дайджесте вопросы доступного пространства в условиях ненадежного поведения horizontalSizeClass и выход Android 17, гид в смешанной реальности с использованием Android XR и живой космос на Metal, иерархия корутин в Android, приложение с расписанием автобусов, скам сети с подписками, домашний сервер с Qwen Code за 25к и многое другое. Подключайтесь!

Читать далее

Делаем свой QML-компонент для Lottie-анимаций с помощью rlottie

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

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

Большинство таких анимаций, которые вы видите в приложениях практически каждый день, сделаны с помощью Lottie. Например, тут, в Telegram, часть анимированных стикеров и эмодзи сделаны как раз с помощью Lottie.

Почему именно Lottie? Lottie — это JSON-based формат векторной анимации, поэтому он легковесный, легко масштабируется, не требует видеокодеков, хорошо выглядит на экранах с разным DPI.

Читать далее

Свой NavigationBar на iOS: large title, поиск и списки на Texture

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

Разбор того, как отказаться от системного UINavigationBar и собрать собственный навигационный бар на обычном UIView: с коллапсирующим large title как у Apple, встроенной строкой поиска и произвольными панелями под заголовком — и так, чтобы он работал и с UITableView, и со списками на Texture (AsyncDisplayKit). Внутри — устройство компонента и честный разбор компромиссов из реального продакшена.

Читать далее

Нетривиальные анимации в мире iOS-разработки

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

Для простых анимаций хватает UIView.animate и CABasicAnimation, но для сложных синхронных цепочек этого мало. Разбираю, почему Timer на 1/60 секунды рвёт анимацию под нагрузкой, и как CADisplayLink решает это, синхронизируясь с реальным обновлением экрана. Показываю свой DisplayLinkAnimator: строго согласованные констрейнты нескольких view, кастомные timing-функции и многоточечные кривые Безье (которых не даёт CAMediaTimingFunction), пауза и возобновление — с примерами кода.

Читать далее

Девять лет, 514 коммитов и один посёлок: как я делал приложение с расписанием автобусов

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

Уже девять лет я делаю приложение с расписанием автобусов для посёлка Иртышский в Омской области. И почти всё это время сам там не живу - уехал через полгода после запуска, а приложение осталось, им до сих пор пользуются.

И сразу скажу: я не программист. Работаю в IT системным аналитиком, а код пишу для себя, как хобби. Захотел бы научиться программировать всерьёз - пошёл бы на курсы и научился. Но мне это никогда не было нужно. Нужно было получить желаемую утилиту, а программирование тут просто инструмент. Это - моё творчество.

А вспомнил я про эти девять лет сегодня вечером. Сегодня 18 июня 2026 года, и ровно семь лет назад, день в день, я научил приложение скачивать расписание из интернета — до этого оно лежало прямо в сборке. Сегодня этот способ убрал, расписание теперь приходит по‑другому. Провозился полвечера, а потом посчитал - приложению‑то уже девять лет.

Читать далее

От потоков к корутинам: как и почему видоизменились примитивы синхронизации в языке Kotlin (Часть 2)

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

В первой части статьи были рассмотрены следующие распространённые способы организации конкурентного кода при работе с потоками и корутинами: критические секции, атомарные переменные, реактивные переменные, барьерная синхронизация.

В этой части будут разобраны другие важные подходы: семафоры, каналы передачи данных, горячие потоки, модель акторов, последовательные обработчики задач, thread confinement.

Для каждого из этих подходов рассмотрим конкретные реализации, выделим плюсы и минусы, приведём примеры использования. В конце объединим все реализации в общую таблицу.

Читать далее

«Это уже тысячу раз делали»: как мы добавили медиаленту в Яндекс Еду для iOS. А потом переделали

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

На первый взгляд, медиалента в мобильном приложении выглядит как стандартная задача: список карточек, автоплей, предзагрузка соседних роликов, несколько состояний загрузки. На практике это оказался один из самых сложных iOS‑компонентов, с которыми мне доводилось работать.

Проблема в том, что медиалента — это не один виджет и не просто плеер внутри ячейки. Это система, которая живёт на пересечении сразу нескольких тяжёлых доменов: динамически собираемый интерфейс, сетевые ограничения, декодирование медиа, менеджмент памяти, жизненный цикл вложенных контейнеров, UX‑требования к мгновенному старту, интеграция в чужие экраны и такие сложные системы, как BDUI, рекомендации, пагинации, и при этом — высокий трафик на массовом сценарии. 

Само собой, любая ошибка в этой конструкции редко проявляется как локальный баг. Обычно она масштабируется: фризы при скролле, чёрные экраны, нестабильный автоплей, рост памяти на длинных списках, нагрев устройства и трудноуловимые падения, которые воспроизводятся только на части устройств и только в условиях реального использования, а не эмуляции.

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

Читать далее

Живой космос на Metal: как я переписывал фон мобильной игры и поднимал FPS с 20 до 120

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

В мобильной разработке мы привыкли, что красивый анимированный фон — это либо видео, либо пара слоёв с CAGradientLayer и медленным параллаксом. Для большинства задач этого хватает. Но иногда хочется большего: настоящий живой космос — туманности, которые медленно перетекают друг в друга, планеты с кольцами, звёзды разных классов и в центре — чёрная дыра с аккреционным диском, как в «Интерстелларе».

У меня есть небольшая аркада-раннер про полёт сквозь космос. Фон там — не картинка, а процедурная сцена, которую целиком рисует фрагментный шейдер: каждый пиксель экрана вычисляется математикой из шума. Сначала всё это жило на SpriteKit, а потом я переписал на Metal — и вот тут началось самое интересное, потому что красивая сцена на десктопе и та же сцена на телефоне — это две очень разные истории.

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

Читать далее

Границы применимости LLM в мобильном UI-дизайне

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

LLM уже умеют быстро собирать мобильные макеты, и на первый взгляд результат часто выглядит убедительно. Кнопки похожи на кнопки, bottom sheet на bottom sheet, экран не разваливается, и его можно показать на обсуждении. Но на практике это всего лишь аккуратный черновик, который ещё нужно как следует доработать: посмотреть компоненты, состояния, навигацию, safe area, длинные тексты и поведение на маленьком экране.

Поэтому предлагаю разобраться, где LLM-инструменты действительно снижают стоимость первой итерации, а где просто переносят сложность на следующий этап: дизайн-ревью, разбор состояний и ручную адаптацию под мобильный контекст. Зафиксируем практические границы применимости LLM при работе с мобильными макетами.

Читать далее

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

Как я завёл нормальный голос в детское приложение, не разорившись и не заставив никого лезть в настройки

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

Я в одиночку делаю детское приложение, где дети учат английский через рисование: рисуют слова, а оно распознаёт рисунок и отвечает голосом. В MVP голос был системный — бесплатный, но звучит как робот из нулевых, пока сам не зайдёшь в настройки и не докачаешь нормальный. Я сделал модалку с инструкцией. Угадайте, сколько людей ей воспользовались. Короче, примерно никто.

Значит, хороший голос должен достаться всем сразу, без единого телодвижения юзера. И при этом дёшево — причём не только по деньгам.

Рассказываю, как я завёл озвучку через ElevenLabs так, что в проде она почти ничего не стоит, работает офлайн и отвечает мгновенно. Ключ оказался в одном наблюдении: всё, что приложение когда-либо скажет, известно заранее. А ещё — почему, когда ты соло и кодишь в паре с агентом, главные проверки в пайплайне работают за ту команду, которой у тебя нет.

Как это устроено

Как я впервые в Google Play публиковался

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

Привет, Хабр

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

Читать далее

Как мы научились видеть иерархию корутин в Android‑приложении: Coroutine Tracer в библиотеке Demeter

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

Отладка корутин в Android — задача, с которой сталкивается каждый разработчик, использующий Kotlin. На один экран могут приходиться десятки вызовов launch и async, но стандартные инструменты показывают потоки, а не корутины. В итоге, когда одна из корутин зависает, разработчик оказывается в тупике: отладчик показывает живой поток, но не показывает, какая корутина на нём выполнялась, в каком suspend‑вызове она остановилась и кто её запустил. Приходится искать причину вслепую — расставлять логи и пытаться воспроизвести проблему вручную. 

Привет, Хабр! Меня зовут Вадим Мезенцев, я занимаюсь разработкой мобильных приложений в Яндекс Go. Сегодня я расскажу, как мы сделали инструмент, который автоматически отслеживает жизненный цикл корутин и показывает их в виде интерактивного дерева — прямо на устройстве, без внешних профайлеров. А самое главное — он в открытом доступе.

Читать далее

Как я навайбкодил игру и выпустил ее на Яндекс Игры

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

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

Читать далее

PaintCAD Mobile 3.0.24 — графический редактор для Android 2.3+ и J2ME

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

Это путешествие длиной в год началось 14 июня 2025 года. До этого я был счастливым обладателем вот этого андроид-телефона Xiaomi Duoqin F22 Pro с кнопочной клавиатурой и Android 12. Экран у него был 640x960 пикселей. Клавиатура как у любого старого телефона - с двумя контролируемыми под андроидом софт-клавишами и кнопкой "Взять трубку", цифровой клавиатурой и джойстиком. И хоть рисовать на нем с этой клавиатуры было удобно как на сименсах 20 лет назад - мощность у него была совсем средняя.

И с покупкой нового телефона помощней, с большим экраном и без клавиатуры - все поменялось так, что пришлось за прошедший год перелопатить весь мобильный PaintCAD.

Ого, неужели!

ZPL, TSPL, Bluetooth и прочая печатная херабора на складе и в магазине: мобильная печать без  костылей

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

На фоне стандартного интереса к терминалам сбора данных и устанавливаемому на них софту, мы наблюдаем повышенное внимание к оборудованию для печати этикеток (также ценников и наклеек), а именно — к мобильным принтерам. Но здесь кроется главная ловушка восприятия. Какая?

Читать далее

Как мы считаем недельное меню в Pikni Food: пачки, остатки и solver вместо списка рецептов

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

Рассказываем, как из идеи «собрать меню на неделю» получилась задача оптимизации: КБЖУ, бюджет, целые упаковки, остатки в холодильнике, цены магазинов и план готовки.

Внутри — почему схема «рецепты → список покупок» быстро ломается, зачем понадобились greedy, simulated annealing и MIP, и почему список покупок оказался почти отдельным продуктом.

Читать далее