Pitch: Reescrevi meu app de React Native pra SwiftUI com usuários pagantes em produção
Fala, pessoal!
Semana passada caiu o primeiro pagamento da Apple do meu app solo: USD 43,87. Não é muito, mas só de ver isso caindo na conta dá um gás de continuar e o caminho até aqui rendeu umas decisões técnicas que acho que valem discussão por aqui.
O app é o Trainer AI, um personal trainer com IA (gera plano de treino, acompanha execução, corrige forma(ainda em desenvolvimento)). Comecei em React Native + Expo, lancei, consegui os primeiros usuários pagantes… e aí tomei a decisão que mais me questionaram: joguei o app RN fora e reescrevi tudo em SwiftUI nativo, com gente pagando em produção.
Por que abandonei o React Native (nesse caso específico)
Não é post de "RN é ruim". RN me levou ao mercado rápido, e pra maioria dos apps eu usaria de novo. Mas pro meu caso:
- Live Activities e widgets de lock screen (treino rodando na tela bloqueada) eram gambiarra atrás de gambiarra via bridge. Nativo, virou um target normal do Xcode.
- O app é iOS-only na prática — minha base pagante tava toda no iPhone. Eu pagava o custo de abstração cross-platform sem usar o benefício.
- Binário menor, cold start mais rápido.
- IA rodando com framework local - nativo me libera muitas API's para explorar tendo tudo localmente
A migração dos usuários existentes foi a parte delicada: escrevi um LegacyMigrator que lê o estado do AsyncStorage do app RN antigo e converte pro modelo novo no primeiro launch da versão nativa. Ninguém perdeu treino, ninguém pagou de novo.
A parte que mais me salvou: nunca coloque a chave da OpenAI no app
Toda chamada de IA passa por um Cloudflare Worker que faz proxy pra OpenAI. O binário do app não tem chave nenhuma. No Worker ficam três camadas:
- Sanitização de input — usuário escreve o que quiser no chat, mas o que chega no prompt é tratado;
- Prompts estruturados em XML — instrução e dado do usuário nunca se misturam na mesma string solta (mitiga prompt injection);
- Validação de output + rate limit por usuário — controlo custo por usuário centralmente, sem depender de update do app.
Custo de IA é margem. Num app de USD ~6-10, uma chave vazada ou um usuário abusando do chat come o lucro do mês em horas. Montar isso depois que já tem tráfego real é bem mais doloroso do que no dia zero.
Os números honestos
- 1º mês: USD 44,06 — 4 vendas (todas Brasil)
- 2º mês: USD 66,45 — 6 vendas (5 Brasil, 1 EUA)
- Primeiro saque: USD 43,87
Sei que não impressiona ninguém. Mas prefiro mostrar o começo de verdade do que aparecer só quando (se) virar case bonito. O que aprendi até aqui: lançar é a parte fácil — fazer alguém pagar é o jogo de verdade. E mexer em ASO, screenshots e onboarding moveu mais o ponteiro do que qualquer feature nova.
Uma decisão de monetização que ainda tô testando: fui de compra vitalícia e agora vou tentar compra vitalícia + trial de 7 dias em vez de assinatura. Promessa mais simples, zero suporte de "como cancelo", mas obviamente limita o LTV.
Queria a opinião de vocês em duas coisas
- Quem já manteve app cross-platform com base pagante: em que ponto (se algum) a reescrita nativa se justificou pra vocês?
- Pra app de IA com ticket baixo: vitalício ou assinatura? Tô genuinamente em dúvida se me arrependo dessa escolha em 1 ano.
O app tá na App Store como Trainer AI, e tô documentando a jornada inteira — o que funciona, o que não funciona e quanto entra.
É isso, pessoal! Qualquer dúvida sobre a migração ou a arquitetura do Worker, só chamar nos comentários.