Система @упоминаний в мобильном приложении: парсинг, автодополнение

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

Разработка и поддержка любых видов мобильных приложений:

Информационные и развлекательные мобильные приложения
Новостные приложения, игры, справочники, онлайн-каталоги, погодные, фитнес и здоровье, туристические, образовательные, социальные сети и мессенджеры, квиз, блоги и подкасты, форумы, агрегаторы
Мобильные приложения электронной коммерции
Интернет-магазины, B2B-приложения, маркетплейсы, онлайн-обменники, кэшбэк-сервисы, биржи, дропшиппинг-платформы, программы лояльности, доставка еды и товаров, платежные системы
Мобильные приложения для управления бизнес-процессами
CRM-системы, ERP-системы, управление проектами, инструменты для команды продаж, учет финансов, управление производством, логистика и доставка, управление персоналом, системы мониторинга данных
Мобильные приложения электронных услуг
Доски объявлений, онлайн-школы, онлайн-кинотеатры, платформы предоставления электронных услуг, платформы кешбека, видеохостинги, тематические порталы, платформы онлайн-бронирования и записи, платформы онлайн-торговли

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

Услуги, которые мы предлагаем
Показано 1 из 1Все 1734 услуг
Система @упоминаний в мобильном приложении: парсинг, автодополнение
Средний
от 1 дня до 3 дней
Часто задаваемые вопросы

Почему упоминания ломаются на масштабе

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

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

Второй сбой — задержки автодополнения. Пока запрос уходит на сервер на каждое нажатие, список подсказок приходит с отставанием в несколько символов, и пользователь выбирает не того человека. Решение — локальный индекс частых контактов и дебаунс с отменой устаревших запросов, чтобы ответ на «@ан» не перетирал ответ на «@анна».

Третий сбой — дубли уведомлений об упоминаниях. При росте аудитории одно событие проходит через несколько обработчиков: создание поста, редактирование, репост, — и каждый шлёт своё уведомление. Нужен идемпотентный ключ «получатель + объект + тип события», по которому повторная доставка гасится.

Разбираем, как это закрывается на уровне архитектуры.

Что даёт выстроенная система упоминаний

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

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

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

Мы собираем систему на Kotlin и нативной отрисовке списка подсказок, чтобы поведение совпадало на обеих платформах. Метрики — время отклика подсказки, доля успешных переходов по уведомлению, число обращений по упоминаниям — выносим в общий дашборд, чтобы эффект был виден в динамике, а не на словах.

Подходы к парсингу и автодополнению: сравнение

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

Вариант Когда подходит Ограничения
Парсинг на клиенте Справочник до нескольких тысяч записей, меняется редко, важна работа без сети Список устаревает между обновлениями приложения; при росте базы растёт память и время поиска
Серверный разбор Большая живая база, частые переименования, единые правила для всех платформ Каждое нажатие клавиши — сетевой запрос; при плохом канале подсказки запаздывают, нужен запасной режим
Гибридная схема Справочник большой, но активная часть узкая (переписка идёт с десятком людей) Сложнее логика слияния: нужно решать, чья версия записи свежее, и чистить устаревшее

Как выбрать под свой профиль

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

Что ломается на стыке

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

Как мы внедряем систему упоминаний

Работу начинаем с аудита: смотрим, как приложение ведёт себя сейчас при вводе «@» — где срабатывает подсказка, где текст уходит как есть, как хранятся идентификаторы упомянутых сущностей. На этом этапе фиксируем крайние случаи: упоминание в начале строки, после знака препинания, внутри ссылки, вставка из буфера, ввод с аппаратной клавиатуры. Каждый случай получает ожидаемое поведение — это база для приёмки, а не догадки на глаз.

Дальше проектируем схему разбора и собираем её по шагам.

  1. Аудит текущего поведения. Прогоняем сценарии ввода на живом приложении, собираем расхождения между платформами и фиксируем, какие сущности вообще можно упоминать.
  2. Схема разбора текста. Определяем грамматику упоминания: допустимые символы, границы токена, правила экранирования. Разбор идёт одним проходом по строке, поэтому ввод длинного текста не тормозит.
  3. Настройка автодополнения. Подсказка запрашивается с задержкой после последнего нажатия и отменяет предыдущий запрос, если пользователь продолжает печатать. Список ранжируем по совпадению и частоте — релевантное оказывается первым.
  4. Связывание с данными. Упоминание храним как идентификатор сущности, а не как текст: при переименовании пользователя или канала ссылка остаётся рабочей.
  5. Проверка сценариев. Прогоняем разбор на подготовленном наборе строк — с эмодзи, смешанными алфавитами, обрывом ввода, удалением символа внутри упоминания. Отдельно проверяем поведение при недоступной сети.
  6. Нагрузочная проверка. Смотрим, как ведёт себя подсказка при большой базе пользователей и на слабом устройстве: время отклика и потребление памяти.
  7. Передача документации. Отдаём регламент разбора, описание формата хранения упоминаний и чек-лист приёмки, чтобы команда заказчика могла развивать систему сама.

После передачи остаёмся на поддержке: изменения в правилах разбора или ранжировании проходят через тот же набор проверок, что и первичная реализация.

Артефакты: конфигурации, схемы, политики доступа

После сдачи проекта у вас остаётся не «папка с исходниками», а комплект, по которому система упоминаний живёт и развивается без нас. Каждый артефакт закрывает свой класс задач: разбор текста, подсказки, права, уведомления, эксплуатацию.

  • Схема разбора упоминаний — формализованное описание того, как парсер находит сущности в тексте: границы токена, набор допустимых символов, поведение на кириллице и латинице, обработка вложенных и повторных упоминаний. Схема привязана к тест-кейсам, поэтому изменение правил сразу проверяется на регрессиях.
  • Конфигурация подсказок — параметры автодополнения: порог срабатывания, размер выдачи, приоритеты сортировки, источники кандидатов (локальный кэш, серверный поиск, недавние контакты). Меняется без пересборки приложения.
  • Политики доступа — матрица «кто кого может упоминать»: приватные каналы, закрытые группы, внешние участники, заблокированные пользователи. Правила проверяются и на клиенте, и на сервере, чтобы обход интерфейса не давал доступа к чужим данным.
  • Регламент уведомлений — когда упоминание превращается в пуш, как группируются повторные, что происходит при офлайне и как ведётся журнал доставки. Отдельно описаны сценарии, где уведомление намеренно не отправляется.
  • Документация по упоминаниям — спецификация формата хранения, контракты серверных методов, описание краевых случаев и инструкция для поддержки: как воспроизвести проблему и что смотреть в логах.
  • Схема миграции и отката — порядок выката, обратная совместимость старых версий клиента, план отключения при деградации.
  • Набор автотестов — покрытие разбора, подсказок и прав доступа, включая негативные сценарии.

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

Кейс: ускорили автодополнение и убрали дубли уведомлений

Клиент — сервис совместной работы с лентой обсуждений. Упоминания работали, но подсказки появлялись с задержкой, а при быстром наборе и правках пользователи получали по два-три уведомления об одном и том же. Разбираем кейс упоминаний: что замеряли, что меняли и какие метрики до/после получили.

Что было до

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

Что изменили

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

Метрики до/после

Метрика До После
Скорость подсказок заметная задержка при наборе подсказка появляется практически сразу
Дубли уведомлений 2-3 пуша на одно упоминание один пуш на сообщение
Ошибочные уведомления регулярные жалобы сведены к нулю

Работу вели наши инженеры на React Native — это позволило переиспользовать логику парсинга между платформами и не дублировать её отдельно под каждую ОС. После релиза число обращений в поддержку по теме уведомлений сократилось, а доля сообщений с упоминаниями выросла: подсказки перестали мешать набору текста.

Чем отличается разбор на клиенте от серверного?

Разница проявляется в момент, когда пользователь набирает символ @ и начинает вводить имя. Клиентский разбор означает, что приложение само находит границы упоминания в тексте и фильтрует список участников по уже загруженному справочнику. Серверный разбор — когда строка уходит на бэкенд, там разбирается, сопоставляется с базой пользователей и возвращается готовый результат. Оба подхода решают одну задачу, но по-разному распределяют нагрузку и задержки.

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

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

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

Частые технические сомнения

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

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

Что будет со старыми версиями приложения, которые ещё в ходу?

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

Не создаст ли автодополнение пиковую нагрузку на сервер?

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

Каждое из этих сомнений мы закрываем на этапе проектирования, а не после запуска: правила парсинга, модель доступа и формат разметки фиксируются в документации и покрываются автотестами.

Обсудим вашу задачу по упоминаниям

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

Вот что мы уточняем на первом разговоре:

  • Где источник сущностей — пользователи, команды, документы, проекты: одна таблица или несколько разрозненных справочников, как они синхронизируются с бэкендом.
  • Как ищется совпадение — по началу строки, по вхождению, по опечаткам; нужна ли латиница рядом с кириллицей и как обрабатываются составные имена.
  • Объём и частота — сколько сущностей в справочнике, сколько запросов в минуту, нужна ли выдача с сервера или достаточно локального кэша на устройстве.
  • Права доступа — видит ли пользователь только своих коллег или весь справочник; как упоминание ведёт себя, если у получателя нет прав на объект.
  • Формат хранения — как упоминание ложится в текст сообщения: идентификатор рядом с отображаемым именем, чтобы переименование не ломало историю.
  • Поведение при удалении — что показывать, если упомянутый пользователь или объект больше не существует.
  • Платформы и интеграции — нужны ли уведомления получателю, переход по тапу в профиль или карточку, работа в офлайне.

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

Опишите задачу — где сейчас хранятся сущности, какие сценарии упоминаний критичны и на каких платформах работает приложение. Вернёмся с оценкой работ, планом внедрения и сроками по каждому этапу.

Наши компетенции:

Последние работы

  • Разработка мобильного приложения для компании FEEDME
    Разработка мобильного приложения для компании FEEDME
    1010
  • Разработка мобильного приложения для компании XOOMER
    Разработка мобильного приложения для компании XOOMER
    903
  • Разработка мобильного приложения для компании RHL
    Разработка мобильного приложения для компании RHL
    1332
  • Разработка мобильного приложения для компании ZIPPY
    Разработка мобильного приложения для компании ZIPPY
    1180
  • Разработка мобильного приложения для компании Affhome
    Разработка мобильного приложения для компании Affhome
    1107
  • Разработка мобильного приложения для компании FLAVORS
    Разработка мобильного приложения для компании FLAVORS
    714