Фёдор Борщёв

Заметки с тегом «Apple»

Как мы запустили мобильное приложение на веб-технологиях и нам чуть не помешал Apple

Мы с клиентом запустили стартап. Он помогает малым локальным бизнесам — кофейням, барбершопам и другим — зарабатывать по модели, которую применяют Amazon и Яндекс.

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

Что за проект

Большие цифровые бизнесы зарабатывают кучу денег на пакетах и подписках. Пакеты повышают средний чек, а подписки помогают получать регулярную прибыль и планировать бюджет. Amazon и Яндекс продают пакет-подписку сразу и на кино, и на доставку товаров. Apple давно сместил фокус с продажи отдельных песен на подписку на Apple Music. Пользователь тоже выигрывает — если вы постоянно пользуетесь сервисами Амазона, месячная подписка отбивается за неделю.

Если вы — владелец кофейни, и хотите продать постоянным клиентам подписку на капучино по утрам, есть нюанс: у Амазона и Яндекса есть миллионы долларов на программистов, а у вас, скорее всего, нет.

Тут на помощь приходит Dozo — проект, в котором собственную подписку или пакет может создать любой малый бизнес — от кофейни до барбершопа.

Вот они, подписки:

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


На самом деле, в нём довольно много нюансов — барбершопу и кафе нужны разные форматы меню; у одного владельца может быть несколько бизнесов, а у одного бизнеса — несколько локаций; каждому сотруднику нужна учетная запись с возможностью считывать QR-коды клиентов, но без возможности менять настройки бизнеса; владельцу бизнеса важно видеть статистику; нужна интеграция с Google Maps, платежным провайдером и SMS API; нужно правильно учитывать налоги при приёме платежей.

Работа над проектом

Любой программист знает, как больно работать с меняющимися требованиями. В этом проекте этого было очень много. Мы вместе с клиентом составили список User Stories и обновляли его после каждой встречи. Это давало уверенность, что при пересмотре планов мы не забудем ничего важного:

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

Для стартапа, который только пытается нащупать своё уникальное товарное предложение, найти своё место на рынке, такие резкие перемены — нормальное положение дел.

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

Часть схемы Event Storming, архитектурного воркшопа, результат которого — схематичное описание системы, с которым согласен каждый участник


Технологии

На бэкенде использовали Python и Django, на фронтенде Vue.js — проверенный стек, с которым у нас большой опыт и экспертиза. Для инфраструктуры использовали проверенные решения: GitHub Actions, Cloudflare и Heroku, для SMS-рассылок подключили Twilio. Для мониторинга взяли Hosted Graphite — стоит дешево, настраивается быстро. Задачи менеджили в привычном нам Бейскемпе.

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

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

Ещё одна вещь, которую мы делали в первый раз — интеграция с Apple и Google Wallet. Карточки товаров из Dozo можно хранить и показывать из родных интерфейсов iOS и Android без запуска Dozo, прямо как авиабилеты. Кстати, наши карточки в электронных кошельках динамические — то есть информация в них регулярно обновляется. Если в вашем проекте нужны wallet-ы — не оставляйте задачу на последние спринты, потребуется время, чтобы разобраться с кастомизацией карточек и обновлением данных.

PWA

Dozo это PWA (Progressive Web App) — сайт, который выглядит и работает как приложение. У него куча плюсов:

  • в отличие от сайтов, оно умеет открываться и работать оффлайн, без интернета;
  • его можно вытащить на рабочий стол, прямо как приложение;
  • у обычных сайтов, на экране постоянно висят кнопки «вперед, назад» и адресная строка, у PWA браузерные контролы скрыты, только наш интерфейс, как у приложений;
  • одно и то же приложение работает сразу и на iOS, и на Android;
  • не нужно проходить жёсткое ревью для каждого обновления.

Если пользовались мобильным сайтом Сбербанка или Тинькофф Банка в 2024-ом году, скорее всего вы сталкивались с этой технологией. Примеры из международного рынка — PWA приложения AliExpress, Twitter, Starbucks и Pinterest.

Невооруженным глазом PWA не отличить от мобильного приложения из Google Play или App Store:

Есть и минус — на iOS нельзя выкладывать PWA в App Store, а значит пользователям гораздо тяжелоее добавить икноку на рабочий стол.

На Android (слева) можно сделать кастомную кнопку установки PWA из браузера, мы сделали баннер наверху экрана. На iOS (справа) такой возможности нет, единственный вариант— зайти в настройки сайта и нажать Add to Home Screen:

Риски PWA мы взвешивали вместе с основателем и CTO Dozo, и решили, что в нашем случае плюсы перевешивают минусы.

Как мы попали в замес борьбы двух Голиафов

Итак, два месяца до запуска. Работа расписана по дням, время — ударно допиливать фичи и запускаться. В начале февраля Apple объявляет, что выключает PWA для европейских пользователей в следующем обновлении iOS.

На примере Spotify: слева как выглядит PWA на iOS 17.3.1, справа — на iOS 17.4 Beta 3. Слева, считай, приложение, справа — вкладка в браузере.

Дело в том, что незадолго до этого Евросоюз принимает закон о защите конкуренции, по которому владельцы платформ (читай Apple) не имеют права ограничивать установку сторонних программ на свои устройства. Apple нехотя подчиняется, но в ответ портит пользовательский опыт для жителей ЕС — мол, вините в этом своих политиков. Есть много мнений и аргументов о том, кто прав в этом споре.

Для нас же это выглядит как сход лавины в горном походе. Сетовать на несправедливость мира глупо, нужно искать путь в обход. Есть несколько вариантов, самый очевидный — засунуть сайт в нативную обертку, типа Capacitor-а, тогда для Apple мы будем выглядеть как самое обычное приложение. Проблема в том, что времени у нас осталось в обрез, а продакшен-опыта с Capacitor у нас не было. Решили запускаться на iOS просто как сайт.

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

Финал

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

Если вы живете в Варшаве — скоро сможете купить подписку на стрижки в барбершоп или комбо из капучино и булочки со скидкой в кофейне через Dozo. А наша команда продолжит поддерживать и развивать продукт после запуска.

Если хотите запустить проект с нами — пишите в телеграм или оставьте заявку на нашем сайте.

Команда

Андрей Бацунов, фронтенд-разработчик,
Алексей Богословский, ведущий бэкенд-разработчик,
Артур Даценко-Боос, фронтенд-разработчик,
Полина Никитина, бэкенд-разработчица,
Иван Седов, фронтенд-разработчик,
Инна Сидорова, руководитель проекта.

Мой сетап

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

Я использую MacBook Pro 14" 2022 года. Когда я работаю дома, ноутбук подключён к монитору LG UltraFine 4K прошлого поколения — кажется это единственный монитор с честной ретиной и нативным для мака DPI. Поколение монитора важно — подробнее см. обзор на «Вёрдже».

Я не использую два дисплея, поэтому ноутбук работает Clamshell mode. Единственное исключение — стримы: для них я открываю на ноутбуке Open Broadcaster Software.

Рабочий стол с двумя дисплеями (редкое состояние)
Мой рабочий стол

В качестве органов управления я использую Happy Hacking Keyboard и Magic Trackpad. Мои пальцы не могут изогнуться, чтобы воспользоваться странной клавишей, которую засовывают в русских раскладках между левым шифтом и z, поэтому я всегда покупаю американские клавиатуры, вот — клавиатура ноутбука:

Клавиатура ноутбука c «длинным шифтом». Видно отключенный тачбар
Клавиатура ноутбука c «длинным шифтом». Видно отключенный тачбар

Полный список железок:

  • MacBook Pro 14" 2022, Apple M1 Max, 64Gb RAM
  • Монитор LG UltraFine 4k на кронштейне Ergotron LX Desk Monitor Arm
  • Клавиатура Happy Hacking Keyboard Pro Hybrid Type-S
  • Внешний тачпад Magic Trackpad 2
  • Веб-камера Razer Kiyo Pro
  • Микрофон Shure SM7B со штангой Blue Compass
  • Микрофонный предусилитель Art Tube PAC
  • Звуковая карта Focusrite Clarett+ 2Pre
  • Наушники Sony MDR-7506

Поскольку я работаю стоя, напишу пару слов про стол. Сначала я работал за обычным икеевским столом, собранным из самой дешёвой столешницы и регулируемых ножек, но в какой-то момент эта конструкция меня достала —из-за высоты стол сильно шатался. Задумав поменять стол, я посмотрел на рынок и сильно удивился — меньше, чем за 20 000 ₽ высокий стол не купить, причём даже самые дорогие экземпляры, судя по обзорам на ютубе, не отличаются надёжностью.

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

Софт

Я не люблю IDE, и в роли редактора кода использую neovim. Долгое время я сидел в Visual Studio Code, но конце 2021 года я устал бороться с увеличивающимся количеством скрепышей фич, плюнул и перешёл на neovim в терминале iTerm2:

Так выглядит экран во время разработки

Основные плагины:

  • coc для автодополнения, которое понимает язык (LSP)
  • fzf для быстрого открытия файлов
  • nerdcommenter, чтобы быстро комментировать куски кода
  • vim-vinegar, когда нужно походить по файловой системе

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

AirPods в один клик

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

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

AirPods в один клик

Оказывается, этот процесс можно сократить до одного клика и пары секунд — есть специальные программы, которые сделали именно для того, чтобы моментально подключать AirPods к компьютеру. Я пользуюсь бесплатным workflow для Alfred, который так и называется AirPods Connector. Если у вас вдруг нет Alfred — не беда, заплатите 400 рублей за ToothFairy, которая делает то же самое, или просто скачайте бесплатный AirBar.

Как жить с тачбаром

Я не знаю ни одного человека, который был бы доволен тачбаром на новых макбуках.

Основная моя претензия к тачбару — зависимость от контекста. Тачбар отвлекает всегда — в бразуере, в редакторе кода, в почте. Особенно злит, когда работаешь с текстом, думаешь о смысле, а у тебя перед глазами мельтешат варианты замены слов или кнопки с ненужными действиями. Я гораздо быстрее нажму хоткей или наберу слово до конца, чем перенесу руки с клавиатуры на тачбар. Хоткеи и набор — действия автоматические. А к тачбару привыкнуть невозможно — он всегда разный.

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

В общем, тачбар — зло. Без которого, однако, не купить новый макбук, только если урезанную версию. Так что, если вы обладатель макбука с тачбаром, почитайте мой рецепт борьбы с ним.

Сделать сразу: отключить зависимость от контекста

Заходим в настройки клавиатуры: Apple → System Preferences → Keyboard, и выбираем в селекторе «Expanded Control Strip»:

Apple → System Preferences → Keyboard

В таком случае вы получаете обычный набор сенсорных клавиш, который всегда перед глазами. И больше ничего не прыгает!

Тачбар, похожий на клавиатуру старых маков

Посерьезнее: избавиться от случайных нажатий

После двух месяцев в попытках привыкнуть не нажимать на верхнюю панель, я начал копать дальше. В первую очередь, я попробовал освободить зоны, в которых ложные нажатия происходили чаще всего. Это делается через ту же панель настроек клавиатуры: Apple → System Preferences → KeyBoard

У меня получилось так:

Слева и справа пустые места — сюда я чаще всего нажимал случайно.

Слева и справа пустые места — сюда я чаще всего нажимал случайно.

Совсем для гиков: извлечь пользу

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

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

Тачбар без сенсорных зон

При нажатии Option появляются элементы управления яркостью и громкостью:

Элементы упрваления громкостью и яркостью (BetterTouchTool)

Клево, что тачбар в роли дополнительного дисплея позволил сэкономить место в трее, там теперь так:

Пустой трей в OS X

BetterTouchTool — типичная гиковская программа с огромными возможностями, но с корявым интерфейсом, так что придется с ней поразбираться. Чтобы отключить тачбар, нужно перейти на вкладу TouchBar и нажать на кнопку слева:

Better Touch Tool — 1

и снять вот эту галочку:

Better Touch Tool — 2

Дальше — просто, можно выводить любые данные и добавлять любые виджеты. Или вообще ничего не выводить, оставив пустую полосу — тоже неплохо.

Как вывести трек — написано здесь. Если не разберетесь — пишите, дополню статью.

Дисклеймер: лонгрид Вастрика я читал.

Прыгающие иконки

В маке есть две ужасные фичи — тадам при запуске (вот, Бирман ругается) и выпрыгивающие из дока иконки.

Прыгающая иконка в OSX

На картинке Айтюнс радостно выпрыгивает из дока, чтобы сообщить мне: «Эгей! Я сглючил! Не могу залогиниться в магазин!». Зачем мне об этом знать? Не смог сейчас — сможешь позже. А если я презентацию показываю, или фильм смотрю?

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

Цивилизованного способа запретить иконкам прыгать не существует. Но через терминал — можно: defaults write com.apple.dock no-bouncing -bool TRUE && killall Dock