«Я вас видел». Приложение, которое помнит, с кем вы встречались на конференциях и выставках

Однажды к нам пришли, чтобы создать достойную конкуренцию LinkedIn, «Сетке» и TenChat. Мы взялись за дело и написали приложение для конференций, которое находит контакты по геопозиции. Рассказываем, как воплотили в код идею смелого стартапа, преодолевая технические сложности.

«Я вас видел». Приложение, которое помнит, с кем вы встречались на конференциях и выставках

История проекта

К нам обратился московский предприниматель, уставший терять полезные знакомства на торговых выставках. Так родилось решение: приложение "I saw you", которое автоматически запоминает людей вокруг вас.

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

Мы сделали продукт специально для ивент-индустрии: организаторы могут размещать QR-коды или рекомендовать приложение участникам. А написали его на Kotlin Multiplatform, чтобы сразу охватить обе мобильные платформы с нативным интерфейсом.

Как работает «I saw you»

Приложение через GPS определяет, кто находился рядом с вами в радиусе до 50 метров. Если оба человека хотя бы раз открыли приложение во время мероприятия, они автоматически попадают друг другу в список «Виделись».

После события вы можете открыть приложение и увидеть, с кем пересекались — даже если не успели пообщаться лично.

«Я вас видел». Приложение, которое помнит, с кем вы встречались на конференциях и выставках

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

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

Предусмотрели защиту от навязчивости

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

Так случайное соседство на конференции превращается в продуманный, аккуратный деловой контакт — без визиток, поиска в LinkedIn и неловких уточнений «а вы кто?».

«Я вас видел». Приложение, которое помнит, с кем вы встречались на конференциях и выставках

Определились, что работать будем на Kotlin Multiplatform

Перед нами стоял выбор: делать приложение отдельно под iOS и Android, использовать кроссплатформу вроде Flutter или писать на Kotlin Multiplatform (KMP). Мы выбрали последнее, и вот почему.

KMP дает баланс между эффективностью и UX. Бизнес-логику — сеть, хранение, навигацию пишем один раз, а интерфейсы остаются нативными: под iOS — SwiftUI, под Android — Jetpack Compose. Это дает пользователю привычный опыт, а команда меньше занимается дублированием.

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

В-третьих, мы смотрели в перспективу. Если появятся web- или desktop-версии, KMP позволит расширяться без переписывания всего с нуля — через Compose Multiplatform.

Впрочем, несмотря на опыт, проект «I saw you» не дал нам пройтись по прямой. Почти каждый функциональный блок требовал донастройки, тестов, обходных путей и адаптации под реальность. Ниже рассказываем, с чем столкнулись.

Невидимые сложности геолокации

Центральная функция приложения — определить, кто находился рядом с пользователем на мероприятии. В теории задача простая: получить GPS-координаты и зафиксировать пересечения.

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

Особенно непредсказуемо вели себя устройства Samsung, Xiaomi и старые модели Android.

Ситуация усложнилась, когда начались проблемы с GPS — координаты стали определяться неточно. Чтобы не зависеть только от геолокации, планировалось добавить поддержку QR-кодов и другие способы подтверждения контактов. Например рассматривали не самый очевидный способ — сравнение фоновых шумов.

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

Написали чат на KMP с нуля

Когда мы начинали, в Kotlin Multiplatform не было готовых решений для чатов. Ни библиотек, ни шаблонов — все пришлось собирать вручную: продумывать архитектуру, настраивать WebSocket-соединения и добиваться стабильной работы, даже если приложение свернуто или работает в фоне.

Мы реализовали полноценный real-time чат с:

  • WebSocket-подключением и синхронизацией сообщений в реальном времени;
  • push-уведомлениями, которые приходят даже при закрытом приложении;
  • статусами online/offline, реакциями, прочтением, пагинацией;

  • отложенной отправкой сообщений при потере связи;

  • очередью сообщений, чтобы они не терялись и приходили в нужном порядке;

  • навигацией между экранами и открытием чатов по push-уведомлению;

  • логикой переподключения: если соединение теряется, оно восстанавливается автоматически, по умному алгоритму.


Это было непросто, поскольку Android и iOS по-разному работают с фоновыми задачами, сокетами и переходами между экранами. Часто мы просто пробовали разные подходы, потому что документации по чатам на KMP не было.

Зато теперь у нас есть свое стабильное решение для чатов на KMP — и это стало одной из самых мощных частей проекта. Наш проджект-менеджер Саша как-то даже написала об этом целую статью на Хабре — для разработчиков. Заходите почитать.

Офтоп. Почему отсутствие готовых решений — это вызов

Когда под задачу есть готовые библиотеки и гайды, разработка идет быстрее. Можно сфокусироваться на продукте, подключить проверенные модули, собрать интерфейс, не тратя время на базовые вещи.

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

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

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

Архитектура «на вырост»

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

Мы выбрали микросервисную архитектуру. И каждую зону ответственности — авторизацию, поиск, чаты, хранение профилей — вынесли в отдельные сервисы. Это дало нам гибкость в масштабировании: если начнет «проседать» конкретный модуль, его можно масштабировать независимо от остальных, без перекройки всей системы.

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

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

Про сложности

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

Мы переписывали очередь сообщений, настраивали логику переподключений, обрабатывали edge-кейсы, когда приложение закрыто, но пуш все равно должен дойти, а потом корректно открыть нужный экран.

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

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

Добавим сюда отсутствие готовых библиотек под KMP для мессенджеров (на GitHub решений почти не было), нестабильность SDK, разные баги и ограничения между платформами — и получаем настоящий инженерный челлендж.

Многое работало… почти. Сообщения «почти» доходили, экраны «почти» открывались по пушу. Но чтобы убрать эти «почти» и довести продукт до стабильной боевой версии, ушли недели кропотливой работы.

Вместо итогов

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

На сегодняшний день:

  • приложение опубликовано в RuStore;
  • команда завершила базовые доработки после запуска;

  • следующий шаг — выход в Google Play и App Store;

  • затем — тестирование продукта на реальных конференциях.

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

Если вы думаете о запуске MVP или полноценного продукта — приходите, обсудим. Мы поможем определить: действительно ли вам нужно большое решение сразу, или можно начать с более простого, чтобы быстро проверить гипотезы.

Проконсультируем, покажем похожие кейсы — и соберем то, что нужно. Пишите в личку https://t.me/john081076

Читайте другие кейсы на нашем сайте https://softorium.pro/, подписывайтесь на наш канал https://t.me/+0goGvsMB7wRiYmIy чтобы лучше понять мир ИТ изнутри.

6
2
1
2 комментария