1

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:

  1. Sanitização de input — usuário escreve o que quiser no chat, mas o que chega no prompt é tratado;
  2. Prompts estruturados em XML — instrução e dado do usuário nunca se misturam na mesma string solta (mitiga prompt injection);
  3. 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

  1. Quem já manteve app cross-platform com base pagante: em que ponto (se algum) a reescrita nativa se justificou pra vocês?
  2. 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.

Carregando publicação patrocinada...