Pitch: CriAI — o mesmo app, três caras: a IA cria um app sob medida que roda no seu iPhone. O que aprendi construindo sozinho
Sou o Renato, venho de produto, e há alguns meses construo sozinho o CriAI, um app de iPhone em que você descreve o app que quer ("um controle de gastos, tema escuro, detalhes em roxo") e a IA gera um mini-app funcionando, privado, rodando no seu celular. Não gostou? "Deixa mais clean." Ele muda até ficar do seu jeito. Peça o mesmo controle de gastos três vezes e você recebe três apps com caras diferentes. O cadastro abriu ao público esta semana. Quero contar o que deu trabalho, porque foi ali que aprendi mais.
Arquitetura em uma frase: app nativo em SwiftUI. Backend em AWS (Lambda, API Gateway, DynamoDB e Cognito). O modelo gera um único arquivo HTML/CSS/JS, que roda num WKWebView isolado.
1. Isolamento por origem. No começo, todos os mini-apps compartilhavam o mesmo localStorage, e os dados de um app podiam vazar para outro. Passei a dar a cada app a sua própria origem (no iOS e na web, via subdomínio <appId>.apps...) e fiz uma migração única dos dados antigos.
2. CSP como segunda camada. O código gerado passa por um sanitizador, e a CSP bloqueia fetch, XMLHttpRequest, WebSocket e eval. O mini-app não fala com a internet; só o app nativo fala.
3. A IA "corrigia no escuro". Analisando 5 apps reais, vi o padrão: a IA dizia "testei, corrigi" sem nunca ter executado nada, e ia empilhando remendos. Num deles (Botanix), as fotos em base64 estouraram o localStorage, e o erro (QuotaExceededError) foi silenciado. A solução não foi criar mais regras no prompt, e sim dar dados: o mini-app captura onerror, unhandledrejection e estouro de cota, o app nativo manda isso para um endpoint de telemetria, e a próxima edição da IA recebe esses erros reais do aparelho.
4. Créditos são dinheiro: saldo atômico. O débito usa uma escrita condicional no DynamoDB, há um teto de geração calculado pelo saldo e um alarme para saldo negativo.
5. Pegadinhas da Apple que custaram dias. (a) Um binário gerado com Xcode beta foi recusado (ITMS-90111) mesmo com um "SDK 26.5" que parecia estável: o build do SDK era seed, e eu não tinha conferido. (b) O pagamento por compra no app não creditava porque a biblioteca de verificação devolve os campos em camelCase e eu lia em snake_case.
6. Classificar apps pelo nome não funciona. Os nomes criativos ("Gasty", "Botanix") deixavam 78% dos apps como "Outros". Passei a classificar pelo conteúdo, aproveitando a chamada que já gerava o nome. O custo extra foi zero e "Outros" caiu para 1,4%.
Se quiser testar: iPhone com iOS 18 ou superior, a conta vem com 1.000 créditos grátis e os apps prontos não custam nada para continuar usando. https://apps.apple.com/app/apple-store/id6797077582?ct=tabnews&mt=8
Pergunta sincera para a comunidade: para quem gera código com LLM em produção, como vocês fecham o ciclo de "a IA acha que corrigiu"? Rodar um navegador headless no servidor para validar antes de devolver valeria o custo?