Русский
Пример проекта для iOS

Выпуск LiftCrew AI: наш путь создания фитнес-приложения для iOS с ИИ

Как SEYSO SERVICES INC спроектировала, разработала и выпустила LiftCrew AI в Apple App Store — от первого коммита React Native до групповых тренировок с Claude, синхронизацией в реальном времени, анализом еды по фото и подписками StoreKit 2.

12 мин чтения Автор: SEYSO SERVICES INC

1

Выпущенное приложение iOS

9

Таблиц Supabase

4

Режима соревнований

60

кадров/с в интерфейсе

Задача: групповые тренировки в зале с персонализацией через ИИ

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

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

Почему React Native + Expo для iOS и почему это всё ещё достаточно нативно

Мы выбрали React Native 0.81 на новой архитектуре (Fabric + TurboModules) и Expo SDK 54 с expo-router 6 для файловой навигации. Этот стек позволил использовать общую кодовую базу для iOS и Android, сохраняя нативные модули iOS там, где они важны для взаимодействия: нативный expo-apple-authentication для входа с Apple, нативный StoreKit 2 через react-native-purchases (RevenueCat), фотоплёнку iOS через expo-image-picker , а также Reanimated 4.3 для анимаций с частотой 60 кадров/с в потоке интерфейса.

В результате приложение без проблем проходит проверку Apple (App Store Connect ID 6762237223, Team C23ARGS845), соблюдает Apple Human Interface Guidelines и получает OTA-обновления JavaScript-пакета через EAS — сохраняя всё, что пользователи iOS действительно ощущают.

ИИ: Claude в роли тренера

ИИ-тренер генерирует план занятия, когда команда начинает тренировку. Модель получает состав команды, базовый одноповторный максимум (1RM) каждого участника, историю недавних занятий, оборудование зала и цель текущей тренировки. Она возвращает структурированный JSON-план с упражнениями, схемами подходов и повторений и весом для каждого участника.

По умолчанию мы используем Claude Haiku 4.5 ради скорости и стоимости, с переходом на Claude Sonnet 4 для более сложного планирования тренировок и анализа изображений (фото еды). Ключевой момент: API-ключ никогда не покидает сервер; каждый вызов ИИ проходит через бессерверный прокси Vercel по адресу /api/generate-workout , с аутентификацией по Supabase JWT пользователя. В пакете приложения нет секретов — единственный ключ Anthropic хранится в переменных окружения Vercel.

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

Синхронизация команды в реальном времени без собственного бэкенда

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

Вместо создания отдельного сервиса реального времени мы использовали Supabase Realtime с трансляцией через WebSocket. Каждое завершение подхода, переход к упражнению и изменение состояния участника отправляет небольшое событие в канал занятия. Локальное хранилище Zustand применяет его оптимистично и использует AsyncStorage, если сеть пропадает посреди подхода: тренировка важнее всего, синхронизация выполняется по возможности.

Личные рекорды определяются на клиенте по формуле Эпли относительно сохранённого 1RM пользователя. После занятия максимальный расчётный 1RM для каждого упражнения записывается в профиль и публикуется в ленте команды. При равных рекордах показываются все победители: социальное взаимодействие важнее таблицы лидеров.

Учёт питания по фото с визуальными возможностями Claude

Изначально для питания планировался экран ручного поиска продуктов. После первого прототипа мы от него отказались: никто не хочет вводить «куриная грудка, 142 г» после тренировки ног. Вместо этого пользователь фотографирует тарелку, а Claude Sonnet определяет калории и макронутриенты, возвращая структурированный JSON, который сразу попадает в дневные итоги.

За этим стоит калькулятор BMR/TDEE по формуле Миффлина — Сан Жеора, задающий цели пользователя, кольца дневного прогресса с анимацией при добавлении еды и история за последние 5 дней в столбце JSONB профиля Supabase. Выход из аккаунта и переустановка не удаляют данные — это оказалось одним из наших самых значимых решений.

Командные соревнования: превращаем тренировки в сезон

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

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

Сложные части: платежи, пробные периоды и проверка Apple

Мы использовали RevenueCat с нативным StoreKit 2 на iOS и Google Play Billing на Android. Право доступа определяется единственным флагом pro , продукты — liftcrew_pro_monthly_v2 (CA$4.99/мес.) и liftcrew_pro_yearly_v4 (CA$39.99/год). Бесплатный пробный период 15 дней контролируется сервером в subscriptions — таблице с привязкой к auth.users.created_at — ведь клиентский отсчёт пробного периода буквально приглашает к подмене даты и злоупотреблению переустановкой.

Вебхук RevenueCat по адресу /api/revenuecat-webhook отражает каждое событие подписки в Supabase, поэтому пользователь с истёкшим доступом получает ограничение при следующем запуске даже с устаревшим кешем квитанций. Экран оплаты закрывается автоматически сразу после изменения права доступа.

Проверка Apple выявила важное требование, которое мы не запланировали: правило 1.2 — для пользовательского контента необходимы жалобы и блокировка других пользователей. Мы добавили user_reports — таблицу жалоб, список блокировки для запросов на связь и delete_own_account — RPC для полного удаления собственного аккаунта. При следующей подаче приложение прошло проверку.

Архитектура в одном абзаце

React Native 0.81 + Expo 54 на клиенте. Zustand для состояния с сохранением в AsyncStorage и синхронизацией со столбцами JSONB Supabase, чтобы данные переживали переустановку. Supabase Postgres с RLS в девяти таблицах: пользователи, занятия, упражнения, связи команды, залы, соревнования, push-токены, подписки и жалобы. Supabase Realtime для командных занятий в реальном времени. Бессерверные функции Vercel для ИИ-прокси, вебхука RevenueCat, отправки push-уведомлений и агента поддержки Gmail-to-Linear. Claude для ИИ. RevenueCat для платежей. EAS Build для облачной компиляции iOS/Android. Bebas Neue и DM Sans для типографики, лаймовый #d4ff5a на #0d0d0f для оформления.

Что мы повторили бы, а что — нет

  • Повторили бы: серверные ключи ИИ за прокси с JWT-аутентификацией. Обязательное условие.
  • Повторили бы: Столбцы JSONB для меняющихся структур пользовательского состояния: настроек, питания, планов. Это позволяло двигаться быстрее, чем миграции схемы.
  • Повторили бы: RevenueCat. Сочетание вебхука и StoreKit 2 окупилось при первой же сверке возврата средств.
  • Не повторили бы: запуск без включения требований Apple 1.2 в план с первого дня. Мы понимали, что жалобы и блокировка понадобятся; стоило добавить их уже в первую сборку.
  • Не повторили бы: клиентский отсчёт пробного периода — даже временный. Сразу переносите его на сервер.

Хотите такое для своего приложения iOS?

LiftCrew AI — одно из нескольких приложений iOS, спроектированных и выпущенных SEYSO SERVICES INC. Если у вас есть идея — ИИ, фитнес, продуктивность, B2B — и нужен партнёр, который проведёт её от наброска до публикации в App Store, будем рады обсудить. Нативные Swift и SwiftUI, React Native, Expo, интеграция ИИ, оптимизация App Store и многочисленные нюансы требований Apple — всё это наша работа.

Готовы создать своё приложение для iOS?

Поговорите с командой, выпустившей LiftCrew AI.