Italiano
Caso di studio iOS

Il lancio di LiftCrew AI: il nostro percorso per realizzare un’app fitness iOS basata sull’IA

Come SEYSO SERVICES INC ha progettato, sviluppato e lanciato LiftCrew AI sull’App Store di Apple: dal primo commit React Native a un’esperienza di allenamento di gruppo basata su Claude, con sincronizzazione in tempo reale, analisi dei pasti tramite foto e abbonamenti StoreKit 2.

12 min di lettura Di SEYSO SERVICES INC

1

App iOS pubblicata

9

Tabelle Supabase

4

Modalità di sfida

60

FPS dell’interfaccia

L’idea: allenamento di gruppo in palestra, personalizzato dall’IA

La maggior parte delle app fitness è ottimizzata per un solo utente. LiftCrew è nato da una premessa diversa: ci si allena meglio in gruppo, ma un gruppo di amici raramente condivide lo stesso livello di forza. Il nostro cofondatore immaginava quattro persone impegnate nello stesso esercizio, nella stessa serie, nello stesso momento, ciascuna con il carico giusto sul bilanciere per il proprio fisico. Questa idea apparentemente semplice è diventata il principio fondamentale del prodotto: stesso esercizio, carico personalizzato.

Per realizzarla serviva un collegamento stretto tra un modello IA che comprende la programmazione dell’allenamento, un livello in tempo reale che mantiene sincronizzato un gruppo distribuito e un’esperienza iOS abbastanza naturale da passare inosservata durante una serie pesante.

Perché React Native + Expo per iOS, e perché l’esperienza resta sufficientemente nativa

Abbiamo scelto React Native 0.81 sulla New Architecture (Fabric + TurboModules) ed Expo SDK 54 con expo-router 6 per la navigazione basata sui file. Questo stack ci ha consentito di condividere un’unica base di codice tra iOS e Android, ricorrendo comunque ai moduli iOS nativi dove l’esperienza conta: il modulo nativo expo-apple-authentication per Accedi con Apple, StoreKit 2 nativo tramite react-native-purchases (RevenueCat), il rullino iOS tramite expo-image-picker , e Reanimated 4.3 per animazioni a 60 fps sul thread UI.

Il risultato è un’app che supera agevolmente la revisione Apple (App Store Connect ID 6762237223, Team C23ARGS845), rispetta le Apple Human Interface Guidelines e riceve aggiornamenti OTA del bundle JavaScript tramite EAS, senza rinunciare a ciò che gli utenti iOS percepiscono davvero.

L’IA: Claude come coach dell’allenamento

L’AI Coach genera un piano per ogni sessione quando il gruppo inizia un allenamento. Il modello riceve composizione del gruppo, massimali 1RM di ogni membro, storico recente delle sessioni, attrezzatura della palestra e obiettivo della giornata. Restituisce un piano JSON strutturato con esercizi, schemi di serie e ripetizioni e carichi prescritti per ciascun membro.

Usiamo per impostazione predefinita Claude Haiku 4.5 per velocità e costi, passando a Claude Sonnet 4 per la programmazione più complessa e per la visione (analisi delle foto dei pasti). Fondamentale: la chiave API non lascia mai il server. Ogni chiamata IA passa attraverso un proxy serverless Vercel su /api/generate-workout , autenticato con il JWT Supabase dell’utente. Il bundle dell’app non contiene segreti: l’unica chiave Anthropic risiede nelle variabili d’ambiente Vercel.

Abbiamo aggiunto una cache delle risposte lato client di 1 ora, così riaprire lo stesso piano non consuma token, la sostituzione degli esercizi durante la sessione, con ricalcolo del carico in base all’intensità relativa, e un numero volutamente limitato di tentativi, così una rete instabile non impedisce mai di allenarsi.

Sincronizzazione del gruppo in tempo reale senza un backend su misura

Le sessioni di gruppo sono il cuore sociale dell’app. Quattro persone in tre palestre diverse devono sentirsi come se si allenassero insieme: quando qualcuno completa una serie, tutti lo vedono; quando termina il recupero, tutti avanzano; quando qualcuno raggiunge un record personale, i coriandoli compaiono per tutto il gruppo.

Anziché creare un servizio in tempo reale su misura, ci siamo affidati a Supabase Realtime e alle trasmissioni WebSocket. Ogni serie completata, avanzamento di esercizio e cambio di stato di un membro invia un piccolo evento a un canale della sessione. Lo store Zustand locale lo applica in modo ottimistico e ricorre ad AsyncStorage se la rete cade durante una serie: il sollevamento è sacro, la sincronizzazione fa il possibile.

Il rilevamento dei record personali avviene lato client usando la formula di Epley rispetto all’1RM salvato di ogni utente. Al termine della sessione, l’1RM stimato più alto per ogni esercizio viene salvato nel profilo e trasmesso al feed del gruppo. In caso di record a pari merito vengono mostrati tutti i vincitori, perché il coinvolgimento sociale conta più della classifica.

Registrare i pasti tramite foto con la visione di Claude

Inizialmente la nutrizione doveva essere una schermata di ricerca manuale degli alimenti. L’abbiamo scartata dopo il primo prototipo: nessuno vuole digitare «petto di pollo, 142 g» dopo aver allenato le gambe. L’utente fotografa invece il piatto e la capacità visiva di Claude Sonnet restituisce calorie e macronutrienti in un JSON strutturato che confluisce direttamente nei totali giornalieri.

Dietro c’è un calcolatore BMR/TDEE Mifflin-St Jeor che imposta gli obiettivi dell’utente, anelli di avanzamento giornaliero che si animano man mano che vengono inseriti i pasti e uno storico mobile di 5 giorni salvato in una colonna JSONB del profilo Supabase. Disconnessione e reinstallazione non fanno perdere i dati: si è rivelata una delle nostre decisioni di maggior impatto.

Sfide di gruppo: trasformare gli allenamenti in una stagione

Le sfide di gruppo aiutano gli amici a mantenere la costanza. L’app supporta quattro modalità di punteggio: volume (kg totali sollevati), sessioni (numero di allenamenti completati), record personali (numero di record personali), e serie consecutive (giorni consecutivi di allenamento). Quando una sessione si conclude, i punteggi delle sfide a cui si partecipa vengono calcolati automaticamente e le classifiche si aggiornano per tutto il gruppo.

Il motore di punteggio risiede interamente nelle funzioni Supabase e in Postgres: non esiste un servizio separato per le sfide. Le policy RLS assicurano che l’utente veda soltanto le sfide dei gruppi a cui appartiene davvero. È una lezione classica: quando il livello dati è ben fatto, non servono molti servizi.

Le parti difficili: pagamenti, prove gratuite e revisione Apple

Abbiamo usato RevenueCat con StoreKit 2 nativo su iOS e Google Play Billing su Android. Il diritto di accesso è un unico flag pro , i prodotti sono liftcrew_pro_monthly_v2 (CA$4.99/mese) e liftcrew_pro_yearly_v4 (CA$39.99/anno). La prova gratuita di 15 giorni è controllata lato server nella tabella subscriptions ancorata a auth.users.created_at — perché i timer di prova lato client sono un invito a falsificare la data e abusare delle reinstallazioni.

Un webhook RevenueCat su /api/revenuecat-webhook replica ogni evento di abbonamento in Supabase, così un utente con abbonamento scaduto viene bloccato al successivo avvio anche se la cache delle ricevute non è aggiornata. Il paywall si chiude automaticamente nel momento in cui cambia il diritto di accesso.

La revisione Apple ha evidenziato un requisito importante che non avevamo previsto: la linea guida 1.2 da rispettare: i contenuti generati dagli utenti richiedono un modo per segnalare e bloccare altri utenti. Abbiamo aggiunto una tabella user_reports , una lista di blocco sulle richieste di connessione e una RPC delete_own_account per consentire agli utenti di eliminare completamente il proprio account. L’app ha superato la revisione all’invio successivo.

L’architettura in un paragrafo

React Native 0.81 + Expo 54 sul client. Zustand per lo stato, salvato in AsyncStorage e sincronizzato con colonne JSONB Supabase perché l’app resista alle reinstallazioni. Supabase Postgres con RLS su nove tabelle per utenti, sessioni, esercizi, connessioni del gruppo, palestre, sfide, token push, abbonamenti e segnalazioni. Supabase Realtime per le sessioni di gruppo dal vivo. Funzioni serverless Vercel per proxy IA, webhook RevenueCat, invio push e un agente di assistenza da Gmail a Linear. Claude per l’IA. RevenueCat per i pagamenti. EAS Build per la compilazione iOS/Android nel cloud. Bebas Neue e DM Sans per i caratteri, verde lime #d4ff5a su #0d0d0f per l’aspetto visivo.

Cosa rifaremmo e cosa no

  • Da rifare: chiavi IA lato server dietro un proxy autenticato tramite JWT. Imprescindibile.
  • Da rifare: Colonne JSONB per strutture dello stato utente in evoluzione (impostazioni, pasti, piani). Hanno consentito di avanzare più rapidamente delle migrazioni dello schema.
  • Da rifare: RevenueCat. La combinazione webhook + StoreKit 2 si è ripagata la prima volta che abbiamo dovuto riconciliare un rimborso.
  • Da non rifare: lanciare senza prevedere fin dal primo giorno la conformità alla linea guida Apple 1.2. Sapevamo in teoria che sarebbero serviti segnalazione e blocco; avremmo dovuto includerli nella prima build.
  • Da non rifare: un timer di prova lato client, anche provvisorio. Spostarlo subito lato server.

Vuoi una soluzione simile per la tua app iOS?

LiftCrew AI è una delle diverse app iOS progettate e pubblicate da SEYSO SERVICES INC. Se hai un’idea, basata sull’IA, per fitness, produttività o B2B, e vuoi un partner che la porti da un abbozzo a una scheda attiva sull’App Store, parliamone. Swift nativo, SwiftUI, React Native, Expo, integrazione IA, ottimizzazione per l’App Store e tutti gli aspetti della conformità Apple: è ciò che facciamo.

Vuoi realizzare la tua app iOS?

Parla con il team che ha pubblicato LiftCrew AI.