Обновить

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

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

SayFable — офлайн-библиотека с NLP-разметкой, синтезом на 68 языков и чатом по книге

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

Привет, Хабр! В прошлых статьях я рассказывал про локальный переводчик с синтезом голоса на кабардинском и про то, как собрать полный NLP-стек для «финального босса лингвистики» из старых словарей. За прошедшие месяцы весь этот стек - лемматизация, POS, NER, тональность, эмбеддинги, синтез - переехал с Python/Flask на десктопе в Swift-приложение на iOS и заодно перерос сам себя: начиналось всё как синтезатор речи для одного языка, а выросло в персональную библиотеку для любого контента - книги, статьи, подкасты, видео, музыка, файлами или ссылками. Полгода на голом Swift 6, вечерами и выходными.

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

Читать далее

Новости

Как измерить собственный обход блокировок: восемь механизмов, которые не выполнялись ни разу

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

Мы делаем RCQ, мессенджер со сквозным шифрованием и открытым кодом (AndroidiOSпротокол). В нашем основном регионе приложение блокируют, поэтому обход встроен внутрь клиента: sing-box в самом приложении, пул релеев, подписанный конфиг с их списком, запасной путь через CDN.

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

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

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

Читать далее

Погружение в One‑Time Events в Android

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

Представьте, перед вами задача – после авторизации пользователя навигировать его на главный экран, или показать snackbar, например, об ошибке.

В Android для таких событий есть специальное название – One-Time Events, или же просто Effects – события, которые мы отправляем UI из ViewModel и хотим, чтобы они обработались ровно один раз.
И они отличаются от состояния экрана! Состояние существует всегда, а effect отправляется и обрабатывается единожды; в состоянии существуют данные, с которыми user взаимодействует, или которые повторно могут отображаться на экране, когда как effect — совершенно противоположное.

Моделировать такой паттерн можно несколькими способами: через состояние, SharedFlow или Channel. В этой статье мы разберем на простом примере каждый подход и обсудим минусы и плюсы, а также обсудим лучшее обходное решение!

Читать далее

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

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

Что будет, если платить детям за то, что они помыли посуду? Будут ли их мотивировать только деньги? Или есть что-то важнее?

Однажды мы сделали в приложении Альфа-Банка раздел «Детские задания». Это одна из ключевых фич детского банка, которая позволяет родителям и детям создавать задания, договариваться о награде и отмечать их выполнение. Но почти сразу стало понятно, что главный вопрос здесь совсем не про интерфейс, а про то, какую роль вообще должны играть такие задания в отношениях между ребёнком и родителями.

И, кажется, ни одна функция детского банка не вызывала столько споров, как задания: «А что дальше? Будем платить детям за уборку комнаты? За пятёрки? За то, что они вообще соизволили вынести мусор?»

Для многих детских задания выглядят именно как семейный маркетплейс, где ребёнок выставляет счёт за каждое полезное действие. Когда мы начинали делать эту фичу в Альфа-Банке, мы тоже боялись скатиться к «Вынеси мусор — получи 50 рублей». Но что, если это будет не про оплату действий, а про развитие самостоятельности?

У нас две аудитории: родители (которые хотят быть наставниками, а не банкоматами) и дети 6–13 лет (для которых карта — первый опыт обращения с деньгами). Привет, меня зовут Алексей Богомолов, я дизайнер цифровых продуктов, я расскажу, как мы стартовали с парой неочевидных гипотез и о том, как некоторые результаты нас сильно удивили.

Читать далее

Offline‑first PWA на примере фитнес‑трекера

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

Привет, меня зовут Сергей Цибульченко, я fullstack‑разработчик. На хабре уже есть несколько статей про PWA, но они не раскрывают всех подводных камней данной технологии, я с этим лично столкнулся когда делал пет‑проект по этим статьям.

Для начала, что такое PWA? Это веб‑страница которая выглядит и ведёт себя как приложение, но при этом имеет технические ограничения веб‑страницы.

Читать далее

Picture-in-Picture в iOS: от запуска до переключения контента

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

С системной функцией Picture-in-Picture (PiP) сталкивались, пожалуй, все владельцы iPhone: кто-то смотрит видео на фоне переписки, кто-то общается по видеосвязи в любимых мессенджерах. Для пользователя это просто удобство, а для разработчика видеосервиса — отдельный механизм со своей инфраструктурой, жизненным циклом и набором ограничений. В этой статье я разберу интеграцию PiP как встроенного плеера: от первого запуска до переключения контента. Поделюсь нюансами, с которыми вы точно столкнётесь на практике, и покажу, как обойти типовые грабли.

Читать далее

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

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

В первой части мы разобрались как Dart отличает число от объекта. Эти знания нам пригодятся, чтобы разобраться в дальнейших хитростях сборщика.

Перед нами стоит самый главный вопрос: А как сборщик все-таки за собой убирает? 

Молодое и старое поколение.

Что происходит в обычном build() у Flutter-виджета? За один кадр создается куча временных объектов: EdgeInsets, Padding, промежуточные TextStyle, какие-то списки, замыкания. Живут они до следующего ребилда(Не учитывая const).

Также у нас есть и другая категория объектов, которые живут долго: синглтоны, кэши, репозитории, состояние приложения.  Они создаются один раз  и живут все время работы.
Отсюда вывод, если молодые объекты пересоздаются пачками, а старые в основном живут, то убирать их одинаково не выгодно. Именно поэтому Dart делит кучу на 2 поколения...

Читать далее

1823 коммита за четыре месяца в четыре руки с LLM: что получилось, а что чуть не убило проект

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

Четыре месяца, 1823 коммита и около 200 000 строк кода: мобильное приложение для изучения английского, почти целиком написанное через LLM-агента. Я формулировал задачи, ревьюил и принимал архитектурные решения, но код руками набирал редко.

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

Внутри: конституция проекта в CLAUDE.md, четыре слоя храповиков (включая обёртку над git, которая не даёт обойти хуки), разбор пяти причин, почему анимация рвалась на реальном Android, и слоистая память на pgvector с локальными эмбеддингами.

Читать далее

Тренажер ТРИЗ для инженеров

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

Я давно работаю инженером и когда узнал про ТРИЗ очень заинтересовался. Изучив все приемы пришел к выводу - а ведь не надо даже в наше время уже сидеть и долго мыслить над проблемами разработки ведь все основные шаблоны уже описаны. А ведь каждый шаблон это фактически выход из определенной ситуации и проблемы. В начале я сделал приложение в котором с начало показывается название приема и скрыто его значение. По типу приложения для заучивания слов. Но это мне показалось не очень интересным и скучным, поэтому долго я им не прозанимался и вскоре забыл про него.

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

И вот через несколько дней появилось мое приложение. Ну а теперь подробней о нем.

Читать далее

Сколько токенов в секунду реально выдаёт Mac mini M4

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

Дисклеймер: я держу сервис аренды маков, поэтому у меня под рукой флот одинаковых машин и повод их гонять. Цифры ниже с этих машин, методика описана полностью, данные открыты под CC BY. Ссылок на сервис в статье нет.

Читать далее

Мобильная разработка за неделю #641 (27 июля — 2 августа)

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

В этом дайджесте дистрибуция iOS‑приложения без App Store и 5 лет Compose, верификация Android разработчиков и нагрев iOS-устройств как продуктовая метрика, локальные LLM на iPhone, “бумажный” асинхронный Kotlin, ускорение корутин, пошаговая инструкция по внедрению скелетон-загрузок, проговаривания мыслей для ИИ и многое другое. Заходите!

Читать далее

Предзагрузил пачкой — получил N² запросов. Как expire_on_commit превращает оптимизацию в квадрат

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

Бывают ошибки, которые не видит ни ревью, ни тесты: код отрабатывает правильно, прогон зелёный, а запросов к базе он делает в сто раз больше прежнего. Я убрал из фонового планировщика классический N+1 — самым что ни на есть учебным способом — и чуть не выкатил в прод версию, где нагрузка росла как квадрат числа пользователей. Разбираемся с замерами в руках: при чём тут expire_on_commit, почему предзагрузка пачкой сама по себе ни в чём не виновата и как одна строка превращает цикл в N².

Читать далее

Уведомления на Android без Google: почему UnifiedPush через публичный ntfy у вас не работает

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

Как вы помните мы делаем мессенджер. Google-сервисы в нашем основном регионе недоступны, значит FCM отпадает, что мы с этим сделали?

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

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

Читать далее

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

SOLID в реальном мире. OCP без «давайте сразу сделаем расширяемо»

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

Дисклеймер: статья для разработчиков уровня junior и middle, которые знакомятся с принципами чистого кода и SOLID. Примеры кода — PHP 8.1+.

Всем доброго дня! На связи Валевич Артем — тимлид в компании AGIMA. В первой части серии мы разобрали Single Responsibility Principle на кейсе системы отзывов и пришли к простому выводу:

Читать далее

Локальные LLM на iPhone: память, Core ML, MLX и ограничения

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

Всем привет! Меня зовут Никита Нагорнов, я iOS-разработчик в компании «Исходный Код». В этой статье разберем, как запускать локальные LLM на iPhone.

Поговорим про:

1. Архитектуру Apple Silicon и Unified Memory — почему не можем использовать всю доступную память;

2. Память, квантование и KV Cache — где приложения начинают падать и как это отловить;

3. Core ML и MLX — чем отличаются, где какой быстрее и почему нельзя всё запускать на нейронном процессоре;

4. Температуру и троттлинг — что происходит с телефоном на длинной сессии;

5. Гибридный пайплайн — как взять сильные стороны обоих фреймворков и получить стабильную генерацию.

Читать далее

Асинхронный Kotlin. Обзор новинки

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

Приветствуем, Хабр.

Как знают наши постоянные читатели, в последние пару лет мы регулярно заходим на территорию языка Kotlin. Базовой литературы по Kotlin сейчас достаточно, но сегодня мы хотим презентовать вам новинку для настоящих профессионалов — «Асинхронный Kotlin». Книга подготовлена Яной Седовой @Ioanna на основе её собственного курса «Kotlin Coroutines & Flow для Android: от основ до production» размещённого на платформе «Степик». Яна Седова активно работает с этой платформой, вот, что она успела на ней разместить.

Читать далее

Делаем модуль на C++ для приложения React Native

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

Я не планировал переписывать приложение React Native на C++.

Большая часть приложения прекрасно работала на TypeScript: экраны, формы, валидация, навигация, логика продукта — все это находилось именно там, где нужно. 

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

Поначалу все звучало слишком просто. Написать интерфейс на TypeScript, позволить Codegen генерировать контракты, перенести основную логику на C++, зарегистрировать модуль на обеих платформах и использовать его из React Native как любой другой модуль.

Спойлер: да, это работает.

Чистый модуль Turbo Native на C++ действительно может дать вам одну реализацию для Android и iOS, типизированную границу через Codegen, меньшие накладные расходы, чем у старого Bridge, и удобный способ повторного использования существующего кода на C или C++ внутри приложения React Native.

Спойлер номер два: код на C++ — это не самая сложная часть.

Самое сложное начинается вокруг: CMake, NDK, Xcode, Objective-C++, время жизни среды выполнения JSI, регистрация модулей, границы потоков, владение памятью, обработка ошибок, сборки Expo, сторонние библиотеки и вопрос, который никто не хочет задавать слишком поздно — действительно ли этот модуль должен быть нативным?

В этой статье я подробно расскажу о создании C++ Turbo Native модуля для React Native: где этот подход полезен, где он добавляет скрытые затраты на поддержку, чем отличается регистрация для Android и iOS, почему важна обертка TypeScript и почему сам TurboModule должен оставаться «тонким».

Читать далее

Верификация Android разработчиков: что будет с устройствами в России

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

Привет, Хабр! Это SafeMobile. Прошлым летом Google объявил, что на Android телефоны можно будет устанавливать приложения только от проверенных разработчиков. С тех пор нас регулярно спрашивают, что будет с устройствами, которыми управляет MDM – могут ли они остаться без управления, будут ли проблемы с распространением инхаусного софта и т.д.

В этой статье мы расскажем, что узнали – если на устройствах нет сервисов Google, можно не беспокоиться, но и на сертифицированных Google устройствах в РФ, похоже, всё хорошо. Детали под катом.

Верифицироваться

Публикуем iOS‑приложение без Мака и без Visa: пошаговый разбор

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

Дисклеймер: я делаю сервис аренды Mac mini (ссылка в профиле), поэтому тема мне близка профессионально. В статье нет ссылок на него и не будет рекомендаций его выбрать — только разбор всех путей, которыми пользуюсь сам и которые видел у коллег.

Читать далее

Как перейти в ИТ и создать мобильное приложение с ИИ: история разработчика «ЧитКита»

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

Наталья Новикова пришла в разработку из ветеринарии и начинала как самоучка — с курсов по Java. В рамках дипломного проекта онлайн‑магистратуры МФТИ «Разработка ИТ‑продукта» она создала продукт в новой для себя сфере — мобильное приложение для детского чтения на базе искусственного интеллекта. Наталья опубликовала его в RuStore и получила первые 44 платные подписки еще до защиты диплома.

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

Читать далее
1
23 ...