Lancer LiftCrew AI : notre parcours de création d’une application iOS de fitness propulsée par l’IA
Comment SEYSO SERVICES INC a conçu, développé et lancé LiftCrew AI sur l’App Store d’Apple — du premier commit React Native à une expérience d’entraînement en groupe propulsée par Claude avec synchronisation en temps réel, analyse des repas par photo et abonnements StoreKit 2.
1
Application iOS livrée
9
Tables Supabase
4
Modes de défi
60
images/s pour l’interface
Le mandat : s’entraîner en groupe, avec une personnalisation par IA
La plupart des applications de fitness sont optimisées pour une seule personne. LiftCrew est parti d’un autre principe : on s’entraîne mieux en groupe, mais les amis ont rarement le même niveau de force. Notre cofondateur imaginait un groupe de quatre réalisant le même exercice, la même série, au même moment — chacun avec la charge adaptée à son corps. Cette idée apparemment simple est devenue le principe fondamental du produit : même exercice, charge individualisée.
Sa réalisation exigeait une boucle étroite entre un modèle d’IA comprenant la programmation d’entraînement, une couche temps réel gardant un groupe distribué synchronisé et une expérience iOS assez native pour se faire oublier pendant une série lourde.
Pourquoi React Native + Expo pour iOS (et pourquoi l’expérience reste suffisamment native)
Nous avons choisi React Native 0.81 sur la New Architecture (Fabric + TurboModules) et Expo SDK 54 avec expo-router 6 pour la navigation basée sur les fichiers. Cette pile nous a permis de partager une base de code entre iOS et Android tout en utilisant des modules iOS natifs là où l’expérience compte : expo-apple-authentication natif pour Se connecter avec Apple, StoreKit 2 natif via react-native-purchases (RevenueCat), la photothèque iOS via expo-image-picker , et Reanimated 4.3 pour des animations à 60 images/s sur le thread d’interface.
Le résultat est une application qui passe proprement la revue Apple (identifiant App Store Connect 6762237223, équipe C23ARGS845), respecte les Apple Human Interface Guidelines et reçoit des mises à jour OTA du bundle JavaScript via EAS — sans sacrifier ce que les utilisateurs iOS ressentent réellement.
L’IA : Claude comme coach d’entraînement
Le coach IA génère un programme par séance lorsqu’un groupe commence un entraînement. Le modèle reçoit la composition du groupe, les références 1RM de chaque membre, l’historique récent des séances, le matériel de la salle et l’objectif d’entraînement du jour. Il renvoie un programme JSON structuré avec les exercices, les séries/répétitions et une charge prescrite par membre.
Nous utilisons par défaut Claude Haiku 4.5 pour la rapidité et le coût, avec recours à Claude Sonnet 4 pour la programmation plus complexe et la vision (analyse de photos de repas). Point crucial : la clé API ne quitte jamais le serveur ; chaque appel IA passe par un proxy serverless Vercel à /api/generate-workout , authentifié avec le JWT Supabase de l’utilisateur. Le bundle de l’application ne contient aucun secret — l’unique clé Anthropic réside dans les variables d’environnement Vercel.
Nous avons ajouté un cache de réponses côté client d’une heure (rouvrir le même programme ne consomme ainsi aucun token), la substitution d’exercices en cours de séance (le modèle recalcule la charge de remplacement selon l’intensité relative) et un nombre de tentatives volontairement limité pour qu’un réseau instable n’empêche jamais l’utilisateur de s’entraîner.
Synchronisation du groupe en temps réel sans backend personnalisé
Les séances de groupe sont le cœur social de l’application. Quatre personnes dans trois salles différentes doivent avoir l’impression de s’entraîner ensemble : lorsqu’une personne termine une série, tout le monde le voit ; lorsque le repos se termine, tout le monde avance ; lorsqu’une personne bat un record personnel, tout le groupe voit les confettis.
Au lieu de créer un service temps réel sur mesure, nous nous sommes appuyés sur Supabase Realtime et ses diffusions WebSocket. Chaque fin de série, passage à l’exercice suivant et changement d’état d’un membre envoie un petit événement dans un canal propre à la séance. Le store local Zustand l’applique de manière optimiste et se replie sur AsyncStorage si le réseau tombe en pleine série — l’effort est sacré, la synchronisation fait au mieux.
La détection des records personnels s’exécute côté client avec la formule d’Epley par rapport au 1RM enregistré de chaque utilisateur. En fin de séance, le 1RM estimé le plus élevé par mouvement est enregistré dans le profil et diffusé dans le fil du groupe. Les records ex æquo affichent tous les gagnants, car la dynamique sociale compte davantage que le classement.
Journal alimentaire par photo avec la vision de Claude
La nutrition devait initialement prendre la forme d’un écran de recherche manuelle d’aliments. Nous l’avons abandonné après le premier prototype — personne ne veut saisir « poitrine de poulet, 142g » après une séance jambes. L’utilisateur prend plutôt une photo de son assiette, et la vision de Claude Sonnet renvoie les calories et macronutriments en JSON structuré, directement intégrés aux totaux quotidiens.
En arrière-plan, un calculateur BMR/TDEE Mifflin-St Jeor définit les objectifs de l’utilisateur, des anneaux de progression quotidiens s’animent à chaque repas et un historique glissant de 5 jours est conservé dans une colonne JSONB du profil Supabase. La déconnexion et la réinstallation ne font pas perdre les données — cela s’est révélé l’une de nos décisions les plus importantes.
Défis de groupe : transformer les entraînements en saison
Les défis de groupe incitent les amis à revenir. L’application propose quatre modes de score — volume (total de kg soulevés), séances (nombre d’entraînements terminés), records personnels (nombre de records personnels), et séries de jours (jours d’entraînement consécutifs). À la clôture d’une séance, les défis concernés comptabilisent automatiquement les résultats et les classements sont actualisés pour tout le groupe.
Le moteur de score réside entièrement dans les fonctions Supabase et Postgres — aucun service de défis distinct. Les politiques RLS garantissent qu’un utilisateur ne voit que les défis des groupes auxquels il appartient. Une leçon classique : lorsque la couche de données est solide, peu de services suffisent.
Les difficultés : paiements, essais et revue Apple
Nous avons utilisé RevenueCat avec StoreKit 2 natif sur iOS et Google Play Billing sur Android. Le droit d’accès est un simple indicateur pro , les produits sont liftcrew_pro_monthly_v2 (CA$4.99/mois) et liftcrew_pro_yearly_v4 (CA$39.99/an). L’essai gratuit de 15 jours est contrôlé côté serveur dans une table subscriptions ancrée sur auth.users.created_at — car les compteurs d’essai côté client invitent à falsifier la date et à abuser des réinstallations.
Un webhook RevenueCat à /api/revenuecat-webhook répercute chaque événement d’abonnement dans Supabase, de sorte qu’un utilisateur dont l’abonnement a expiré voit son accès limité au prochain lancement, même si son cache de reçus est périmé. L’écran d’abonnement se ferme automatiquement dès que le droit d’accès change.
La revue Apple a révélé une exigence majeure que nous n’avions pas prévue : la directive 1.2 et sa conformité — les contenus générés par les utilisateurs exigent un moyen de signaler et de bloquer d’autres utilisateurs. Nous avons ajouté une table user_reports , une liste de blocage pour les demandes de connexion et une RPC delete_own_account pour permettre aux utilisateurs de supprimer intégralement leur compte. L’application a passé la revue à la soumission suivante.
L’architecture en un paragraphe
React Native 0.81 + Expo 54 côté client. Zustand pour l’état, persisté dans AsyncStorage et synchronisé avec des colonnes JSONB Supabase afin de résister à la réinstallation. Supabase Postgres avec RLS sur neuf tables pour les utilisateurs, séances, exercices, connexions de groupe, salles, défis, tokens push, abonnements et signalements. Supabase Realtime pour les séances de groupe en direct. Des fonctions serverless Vercel pour le proxy IA, le webhook RevenueCat, l’envoi push et un agent d’assistance Gmail vers Linear. Claude pour l’IA. RevenueCat pour les paiements. EAS Build pour la compilation iOS/Android dans le cloud. Bebas Neue et DM Sans pour la typographie, du vert citron #d4ff5a sur #0d0d0f pour l’apparence.
Ce que nous referions — et ce que nous éviterions
- À refaire : des clés IA côté serveur derrière un proxy authentifié par JWT. Non négociable.
- À refaire : Des colonnes JSONB pour les structures évolutives de l’état utilisateur (paramètres, repas, programmes). Elles ont évolué plus vite que ne l’auraient permis des migrations de schéma.
- À refaire : RevenueCat. L’association webhook + StoreKit 2 s’est rentabilisée dès notre premier rapprochement de remboursement.
- À éviter : lancer sans intégrer la conformité Apple 1.2 dès le premier jour. Nous savions en théorie qu’il faudrait signalement et blocage ; nous aurions dû les livrer dès la première version.
- À éviter : un compteur d’essai côté client — même provisoire. Placez-le d’abord côté serveur.
Vous voulez cela pour votre application iOS ?
LiftCrew AI est l’une des applications iOS conçues et lancées par SEYSO SERVICES INC. Si vous avez une idée — IA, fitness, productivité, B2B — et cherchez un partenaire capable de la mener de l’esquisse à une fiche App Store en ligne, parlons-en. Swift natif, SwiftUI, React Native, Expo, intégration IA, optimisation App Store et toutes les exigences de conformité Apple : c’est notre métier.
Prêt à créer votre application iOS ?
Échangez avec l’équipe qui a lancé LiftCrew AI.