Система @згадок у мобільному додатку: парсинг, автодоповнення

**@згадування** в чатах і соцмережах часто працюють ненадійно: ламаються при зміні username, не надсилають сповіщення, або пошук користувачів гальмує. Один з наших клієнтів втратив 15% посилань після перейменування учасників — довелося переписувати систему з нуля. За 5 років ми реалізували понад 15

Розробка та підтримка будь-яких видів мобільних додатків:

Інформаційні та розважальні мобільні програми
Новинки, ігри, довідники, онлайн-каталоги, погодні, фітнес та здоров'я, туристичні, освітні, соціальні мережі та месенджери, квіз, блоги та подкасти, форуми, агрегатори
Мобільні програми електронної комерції
Інтернет-магазини, B2B-додатки, маркетплейси, онлайн-обмінники, кешбек-сервіси, біржі, дропшиппінг-платформи, програми лояльності, доставка їжі та товарів, платіжні системи
Мобільні програми для управління бізнес-процесами
CRM-системи, ERP-системи, управління проектами, інструменти для команди продажів, облік фінансів, управління виробництвом, логістика та доставка, управління персоналом, системи моніторингу даних
Мобільні програми електронних послуг
Дошки оголошень, онлайн-школи, онлайн-кінотеатри, платформи надання електронних послуг, платформи кешбеку, відеохостинги, тематичні портали, платформи онлайн-бронювання та запису, платформи онлайн-торгівлі

Це лише деякі з типів мобільних додатків, з якими ми працюємо, і кожен із них може мати свої специфічні особливості та функціональність, а також бути адаптованим під конкретні потреби та цілі клієнта.

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

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

Часті запитання

Останні роботи

  • image_mobile-applications_feedme_467_0.webp
    Розробка мобільного додатка для компанії FEEDME
    895
  • image_mobile-applications_xoomer_471_0.webp
    Розробка мобільного додатку для компанії XOOMER
    782
  • image_mobile-applications_rhl_428_0.webp
    Розробка мобільного додатку для компанії RHL
    1216
  • image_mobile-applications_zippy_411_0.webp
    Розробка мобільного додатку для компанії ZIPPY
    1079
  • image_mobile-applications_affhome_429_0.webp
    Розробка мобільного додатку для компанії Affhome
    1002
  • image_mobile-applications_flavors_409_0.webp
    Розробка мобільного додатку для компанії FLAVORS
    597

@згадування в чатах і соцмережах часто працюють ненадійно: ламаються при зміні username, не надсилають сповіщення, або пошук користувачів гальмує. Один з наших клієнтів втратив 15% посилань після перейменування учасників — довелося переписувати систему з нуля. За 5 років ми реалізували понад 15 проєктів із згадуваннями для соцмереж та корпоративних чатів, заощаджуючи клієнтам до 40% часу на розробку. Правильно спроєктована система згадок знижує кількість багів на 30% і підвищує точність пошуку на 25%. У цій статті розберемо, як побудувати систему, яка витримує 1000 згадок на хвилину і не втрачає посилання. Синтаксис @згадувань визначений у документації, але на практиці складність у парсингу, автодоповненні та сповіщеннях.

Як працює автодоповнення користувачів?

Сценарій: користувач пише @ал — показуємо список відповідних імен. Логіка відстеження курсора аналогічна хештегам: шукаємо @ перед курсором.

Пошук користувачів

GET /users/search?q=ал&limit=10 — пошук за username та display_name. На стороні БД — WHERE username ILIKE 'ал%' OR display_name ILIKE 'ал%' з GIN-індексом pg_trgm для нечіткого пошуку. Дебаунс 150-200ms на клієнті.

Пріоритизація результатів: спочатку взаємні підписники, потім усі інші. JOIN з follows для сортування за is_mutual.

UI dropdown на iOS

func textViewDidChange(_ textView: UITextView) { guard let mentionQuery = extractMentionQuery(textView) else { hideMentionSuggestions() return } searchUsers(query: mentionQuery) .debounce(for: .milliseconds(200), scheduler: RunLoop.main) .sink { [weak self] users in self?.showMentionSuggestions(users) } .store(in: &cancellables) } func extractMentionQuery(_ textView: UITextView) -> String? { let text = textView.text as NSString let cursorPosition = textView.selectedRange.location let searchRange = NSRange(location: 0, length: cursorPosition) let pattern = "@([\\w\\.]{0,30})$" guard let match = try? NSRegularExpression(pattern: pattern) .firstMatch(in: textView.text, range: searchRange) else { return nil } return (text.substring(with: match.range(at: 1))) } 

При виборі користувача зі списку — вставляємо @username як єдиний токен (замінюємо частково введений текст). Токен не розбивається при редагуванні — при видаленні одного символу видаляється весь @username. На iOS — через NSAttributedString з кастомним атрибутом і перехопленням shouldChangeTextIn. На Compose — TextFieldValue з AnnotatedString, перехоплення змін через onValueChange.

Чому важливо зберігати user_id, а не username?

Проблема: зберігати @username як текст погано — якщо користувач змінить username, згадка зламається. Правильно зберігати згадку як пару (user_id, display_username_at_time):

  • У тілі посту: "Привіт @[user:42|alex]! Як справи?" — кастомний синтаксис з user_id.
  • При відображенні: беремо актуальний username користувача 42 з БД, показуємо клікабельним.
  • Якщо користувач видалив обліковий запис — показуємо @видалений_акаунт сірим.

Парсинг при відображенні додає навантаження — кешуємо display_name за user_id в пам'яті на час сесії.

Порівняння підходів:

Підхід Стійкість до зміни username Навантаження при відображенні Складність реалізації
Зберігання username Низька (ламається) Низька Низька
Зберігання user_id + кеш Висока (не ламається) Середня (кеш) Середня

Зберігання user_id в 3 рази надійніше при зміні імені — це підтверджує практика наших проєктів.

Що таке кастомний синтаксис згадок?

Кастомний синтаксис @[user:42|alex] дозволяє прив'язати згадку до конкретного користувача незалежно від його поточного імені. Це вирішує проблему зміни username та видалення акаунта. Парсинг такого синтаксису на стороні клієнта: при отриманні повідомлення витягуємо user_id з токенів, підставляємо актуальне ім'я з кешу та робимо посилання на профіль. На сервері при публікації зберігаємо вихідний текст з токенами, а при відображенні генеруємо HTML/AttributedString з підстановкою.

Порівняння платформ для реалізації автодоповнення:

Платформа Компонент Відстеження курсора Вставка токена
iOS (Swift) UITextView + UITextInputDelegate NSRange через selectedRange NSMutableAttributedString з NSTextAttachment
Android (Compose) BasicTextField + onValueChange TextFieldValue.selection AnnotatedString з pushStringAnnotation
Flutter TextField + controller TextEditingValue.selection TextSpan з GestureRecognizer

Як реалізувати сповіщення без втрати продуктивності?

При публікації посту або коментаря із згадкою — парсимо user_id з токенів, створюємо записи в notifications (recipient_id, type='mention', source_post_id, actor_id), надсилаємо push через FCM/APNs. Батчинг: якщо в одному пості згадано 5 осіб — 5 окремих сповіщень (кожному своє). Якщо користувача згадано кілька разів за хвилину різними людьми — одне сповіщення «3 згадки». Користувач може вимкнути сповіщення про згадки в налаштуваннях — прапорець notify_mentions у профілі.

Профіль по тапу на згадку

Тап на @username → відкриваємо профіль користувача. Якщо користувача заблоковано або він заблокував мене — показуємо заглушку «Профіль недоступний». Реалізація через UITextViewDelegate.textView(_:shouldInteractWith:in:interaction:) (iOS) або ClickableText з LocalUriHandler (Compose). Для Android використовуємо анотації: при парсингу повідомлення замінюємо токени @[user:42] на AnnotatedString.Range з URL-схемою profile://42, потім у ClickableText перехоплюємо натискання та викликаємо навігацію.

Етапи роботи

  1. Парсинг та підсвічування @згадок у тексті
  2. Автодоповнення з пошуком через API та дебаунсом
  3. Зберігання згадок з прив'язкою до user_id
  4. Push-сповіщення з батчингом
  5. Документація API та схема БД
  6. Інтеграція з існуючим чатом/соцмережею
  7. Тестування на реальних сценаріях (до 1000 згадок на хвилину)
  8. Підтримка після впровадження

Що входить у роботу

  • Консультація щодо архітектури та вибору синтаксису
  • Парсинг та підсвічування згадок у тексті
  • Автодоповнення з дебаунсом та пріоритизацією
  • Зберігання з user_id та кешуванням
  • Push-сповіщення з батчингом
  • Інтеграція з існуючим чатом або соцмережею
  • Документація по API та схемі БД
  • Тестування продуктивності (до 1000 згадок на хвилину)
  • Підтримка протягом 2 тижнів після впровадження

Строки

Парсинг згадок та підсвічування в існуючому тексті — 1 день. Автодоповнення при введенні з пошуком користувачів — 1-2 дні. Сповіщення — ще 1 день. Повна система — 3-5 робочих днів. Вартість розраховується індивідуально, економія на розробці завдяки готовим модулям може скласти до 50% часу.

Зв'яжіться з нами, щоб обговорити інтеграцію. Напишіть на пошту або замовте зворотний дзвінок — ми оцінимо ваш проєкт безкоштовно та запропонуємо оптимальне рішення під ключ. Наша команда має 5+ років досвіду в розробці мобільних додатків та сертифікована за стандартами Apple і Google. Гарантуємо якість та дотримання строків. Отримайте консультацію інженера вже сьогодні.