Мобильное приложение для сети магазинов стройматериалов — «Аквилон»

Разработка гибридного мобильного приложения для компании «Аквилон» на основе готового интернет-магазина с использованием кроссплатформенной технологии React Native.

#интеграции и API
#UI-дизайн
#мобильные приложения

«Аквилон» — супермаркет строительных материалов, один из крупных игроков на рынке Казахстана. Для клиента мы сделали гибридное мобильное приложение на React Native.

Подробнее о том, как для «Аквилона» мы собрали интернет-магазин с ИИ-движком для поиска.

«Аквилон» — интернет-супермаркет строительных материалов, один из крупных игроков на рынке Казахстана. Для сайта мы сделали кроссплатформенное мобильное приложение на React Native. akvilon.kz

После запуска интернет-магазина клиент обратился к нам снова — за мобильным приложением.

Зачем интернет-магазину нужно приложение?

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

— Повысить скорость загрузки: приложение работает быстрее сайта, потому что часть данных уже загружена на смартфон
— Открыть новый канал продаж: например, для клиентов, у которых нет ноутбуков или ПК
— Не отставать от конкурентов: у всех крупных магазинов есть приложения

При этом на рынке Казахстана аналогов мало — а значит, у клиента мало конкурентов. Поэтому даже с учётом этих аргументов мы не до конца понимали, нужно ли приложение пользователям.

Варианты реализации

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

PWA

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

Плюс PWA — их можно дёшево и быстро вывести на рынок. Казалось бы, если нужно просто проверить гипотезу, это хороший вариант. Но с таким же успехом можно провести опрос «Нужно ли вам приложение?» на домашней странице сайта. Такое приложение сложно обновлять и развивать, полноценного цифрового продукта из него не получится. От этого варианта мы отказались.

Нативное приложение

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

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

Кроссплатформенная разработка

Кроссплатформенные приложения, в отличие от нативных, работают в нескольких операционных системах — в данном случае iOS и Android. Фронтенд в таких приложениях написан на JavaScript с использованием мобильных фреймворков. Самые популярные фреймворки для кроссплатформенных приложений — React Native и Flutter.

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

Гибридная разработка

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

Это решение — не только компромисс по цене и скорости между PWA и нативными приложениями. Так как часть функций будет в браузере, можно не писать их с нуля, а взять с сайта. А если гипотеза подтвердится, мы сможем по частям переписывать эти функции и сделать полноценное приложение — например, на React Native.

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

Разделы и функции

Главная польза приложения для клиента — тестирование мобильного канала продаж и способов продвижения и удержания клиента. Поэтому было важно выйти на рынок быстро. Чтобы сократить time-to-market, в приложении мы оставили только базовые фичи:

— Каталог и поиск с фильтрацией

— Корзина и оформление заказа

— Профиль пользователя с бонусной картой

Один из плюсов SPA на Symfony — бэкенд слабо связан с фронтендом, поэтому его можно использовать для нескольких продуктов. В том числе бэкенд с сайта мы взяли для мобильного приложения. В первой версии большая часть контента, отображалась через WebView, фронтенд писали на Vue Native. Потом по частям переписали разделы на React Native — сейчас приложение полностью кроссплатформенное.

Вызовы

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

Представьте, что вы зашли на сайт X. На сайте X есть iframe, в котором отражается сайт Y. Вы авторизовались в этом окне. В норме сайт X не отреагирует на это — а мы хотели, чтобы авторизация на сайте X происходила автоматически после авторизации на сайте Y. Это нужно, чтобы не было багов из-за рассинхрона — например, разного набора отложенных товаров у одного пользователя на сайте и в приложении.

Проблема

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

— Главная и все сопутствующие страницы
— Поиск
— Каталог, фильтры каталога и страницы товаров
— Корзина, оформление заказа и оплата

— Профиль, где больше 20 вложенных страниц

На Vue Native у нас не было переходов как таковых — мы просто подменяли компоненты и показывали их в WebView. Проблемы начались на этапе перехода на React Native.

Фокус с подменой компонентов работать перестал и мы внедрили React Navigation — библиотеку для навигации внутри приложения на React Native. И тут мы столкнулись с проблемой синхронизации — сайт не знает, какие страницы есть у приложения, и наоборот. Мы внедрили обмен данных между этими сущностями через PostMessage. Этот метод работал, пока мы не добавили авторизацию. На этом этапе появилась новая проблема — при открытии авторизации со стороны корзины нужно было сначала открыть страницу профиля. Виновато главное ограничение React Navigation.

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

В этом и есть ограничение React Navigation — эта библиотека не видит информацию о вложенных разделах и не может переходить между ними, если вы не находитесь в корне.

Варианты решений

Эту проблему мы пробовали решить разными способами:

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

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

— Начали передавать более подробную информацию о страницах через PostMessage и этот вариант сработал лучше всех.

Но появилась новая проблема. Из-за этого решения пострадала та часть функционала приложения, которая отображалась не через WebViews — например, кнопка «Назад» перенаправляла не на те страницы.

Что мы сделали

Мы посмотрели на приложения других онлайн-магазинов — в первую очередь, Ozon и Yandex Market. В них не было проблем с навигацией. Но у обоих маркетплейсов нативные приложения на Kotlin и Swift, а мы искали решение для React Native.

В итоге, чтобы обойти ограничение React Navigation, мы все страницы сделали корневыми. Правда, для этого мы дописали часть компонентов этой библиотеки:

— Кастомный routes — добавили методы, которых нам не хватало
— Свой TabNavigators, который скрывает все ненужные корневые страницы, кроме тех, которые нужны на экране прямо сейчас

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

Продвижение

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

Позже люди начали сами находить приложение в магазинах через поиск. В магазинах мы приложение не продвигали — только заполнили все нужные поля и подготовили красивые скриншоты для product page.

Запуск и развитие

Мы боялись, что приложение не примут в магазинах из-за того, что большая часть фичей подгружается через WebView. Внятных гайдлайнов у App Store и Google Play по этому поводу нет — непонятно, почему одни приложения публикуют, а другие нет. Так что риск отказа был, но публикация прошла без проблем.

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

Сразу после запуска мы начали активно собирать фидбек. Мы отвечали быстро, благодарили за высокие оценки и обратную связь. Выясняли проблемы пользователей, которые ставили 1 и 2, и оперативно чинили. Но поначалу у приложения всё равно был низкий рейтинг — оценки ставили в основном те пользователи, которые столкнулись с проблемами.

Чтобы поднять рейтинг, мы быстро добавили форму обратной связи в само приложение сразу после оформления заказа. Так пользователи могли напрямую сообщить о сложностях мимо магазинов приложений. После добавления формы фидбека оценки выросли.

Результат

80% пользователей заходят через Android и 20% — с устройств Apple. У обоих приложений рейтинг выше 4,5. Через приложение оформляется 30% от всех заказов с сайта.

Клиент был доволен — он получил то, что хотел.

Сейчас мы развиваем приложение, чтобы у него были преимущества перед сайтом. Добавили push-уведомления, используем их для новостей об обновлениях в приложении. В будущем планируем запускать через них кампании для повышения retention rate — например, рассказывать об акциях. Ещё в приложении доступен штрихкод бонусной карты, чтобы можно было не носить пластиковую версию.

Похожие кейсы