TIPS 67 · BOCCIATURA

A rejeição antes da Apple

O Greenlight lê a tua app e diz-te o que a pode fazer ser rejeitada pela Apple ou pelo Google Play, antes de a enviares. Como se instala, como se leem os resultados, como pões o Claude Code a usá-lo e o que ele não consegue ver.

O que é e porque importa

Mandas a app para revisão, esperas, e ela volta para trás. Falta o início de sessão com a Apple, ou a conta não se pode apagar, ou a frase que explica porque pedes a câmara é vaga demais. Cada volta são dias perdidos, e muitas vezes o motivo já estava escrito nos teus ficheiros.

O Greenlight é um programa de terminal que faz essa verificação antes de ti. Lê o código, os ficheiros de configuração e, se lha deres, a app já compilada. Depois compara tudo com as regras de revisão da Apple e com as políticas do Google Play. Cada problema tem um nível de gravidade e cita a regra de onde vem. A verificação base não pede conta, não envia nada e não usa a rede. É feito pela Revyl, uma empresa de testes de apps, e o código está aberto no GitHub com licença MIT: usa-se de graça.

É para quem publica sozinho, sem uma equipa que releia as regras da Apple a cada versão. Uma coisa tem de ser dita já: é uma lista de coisas para ver, não um carimbo de aprovação. Lê os ficheiros, não usa a app. Na secção 6 está o que ele não vê.

1. O que verifica

O comando principal chama-se preflight, como a verificação antes da descolagem. Corre cinco verificações de uma vez, a que a documentação chama scanners:

  • metadata: nome, versão, formato do bundle ID (o identificador da app), ícone, link para a política de privacidade e as frases que explicam porque pedes uma permissão. Lê-os no Info.plist ou, nas apps Expo, no app.json.
  • codescan: 24 regras sobre código Swift, Objective-C, React Native e Expo. Por exemplo chaves secretas escritas no código, login com a Google sem o início de sessão com a Apple, contas que se criam mas não se apagam.
  • privacy: o manifesto de privacidade que a Apple pede (PrivacyInfo.xcprivacy) está lá e completo? E se usares SDKs de rastreio, está lá o pop-up ATT que pede permissão para rastrear?
  • playscan: só para projetos Android. As regras do Google Play: o nível de API Android a usar como alvo e os seus prazos, as permissões que pedem um formulário de declaração, os serviços em primeiro plano, a versão do Play Billing para os pagamentos.
  • ipa: a app para iPhone já compilada, o ficheiro .ipa. Verifica as chaves do Info.plist, o ecrã de arranque, os ícones, o tamanho da app e os manifestos de privacidade dos frameworks incluídos. Só corre se lhe passares o ficheiro.

Se na mesma pasta estiverem tanto a parte iOS como a Android, como numa app Flutter ou React Native, verifica as duas numa só passagem.

2. Instala-o e corre a primeira verificação

Instala-se a partir do terminal. No Mac, com o Homebrew, o programa que instala outros programas pelo terminal. Se em vez disso tiveres Go, a linguagem em que o Greenlight está escrito, usa a segunda linha.

Os comandos
brew install revylai/tap/greenlight
go install github.com/RevylAI/greenlight/cmd/greenlight@latest

Depois entra na pasta principal do projeto e corre a verificação. O ponto quer dizer «esta pasta». Demora menos de um segundo.

O comando
greenlight preflight .

Se já exportaste a app para a App Store, junta o ficheiro .ipa: assim verifica também a app compilada, não só o código-fonte. Para Android é igual com --apk ou --aab, o ficheiro que envias para o Play. Põe o caminho do teu ficheiro no lugar do exemplo.

Os comandos
greenlight preflight . --ipa build.ipa
greenlight preflight . --aab app-release.aab

3. Como ler o resultado

Cada problema encontrado traz quatro coisas: o nível de gravidade, a regra da Apple ou da Google de onde vem, o ficheiro onde foi encontrado e uma sugestão para o resolver. Os níveis são quatro:

  • CRITICAL: a rejeição, ou uma instalação que falha, é quase certa. Resolve-se antes de enviar.
  • HIGH: um prazo já publicado, uma declaração obrigatória que falta ou algo que se parte enquanto a app corre.
  • WARN: é provável que o revisor repare e te peça explicações.
  • INFO: boa prática. Não bloqueia nada.

No fim está o veredicto: NOT READY se ainda houver pelo menos um CRITICAL, NEEDS REVIEW se ainda houver HIGH, GREENLIT quando já não houver nenhum dos dois. GREENLIT quer dizer que a verificação dos ficheiros passou, não que a Apple te vai aprovar.

4. Põe o Claude Code a usá-lo

O Greenlight também existe como plugin do Claude Code. O plugin não é o programa: é uma skill, ou seja, uma folha de instruções que diz ao Claude como correr a verificação, ler os resultados, corrigir o código e voltar a correr. Dentro do Claude Code escreve:

Os comandos
/plugin marketplace add RevylAI/greenlight
/plugin install greenlight

O plugin não instala o programa sozinho: fá-lo tu antes, como no passo 2. Depois abre o Claude Code na pasta do projeto e cola:

A mensagem
Corre o greenlight preflight e corrige tudo até passar. Começa pelos CRITICAL, depois os HIGH. Depois de cada ronda de correções volta a correr a verificação. Se um problema te parecer um falso alarme, não mexas no código: para e explica-me porquê.

Os HIGH pus de propósito. As instruções do plugin dão o trabalho por acabado quando já não há nenhum CRITICAL. Mas os HIGH ficam, e entre eles estão precisamente o início de sessão com a Apple que falta e a conta que não se apaga.

Quando um resultado não te for claro, pede que to explique antes de mexeres em alguma coisa:

A mensagem
Explica-me este resultado do Greenlight com palavras simples: [cola a linha]. Diz-me que regra da Apple ou da Google cita, em que ficheiro o encontrou e o que lá está escrito. Depois diz-me se achas que é um problema real ou um falso alarme, e como é que eu o verifico.

E quando já percebeste que é um falso alarme:

A mensagem
Este resultado do Greenlight é um falso alarme: [cola a linha]. Se vier da verificação do código (codescan), cria ou atualiza o .greenlight.yml na pasta principal: baixa a gravidade dessa regra ou exclui só o ficheiro ou a pasta necessários, sem desligar outras verificações. Escreve ao lado um comentário com o motivo. Se vier de outra verificação, não mudes nada e diz-me.

5. Falsos alarmes e verificação automática

O ficheiro .greenlight.yml

Fica na pasta principal do projeto e ajusta a verificação do código, também quando corre dentro do preflight. Para cada regra podes mudar a gravidade (info, warn ou critical) ou desligá-la, e podes excluir pastas, ficheiros ou caminhos.

O ficheiro
rules:
  hardcoded-ipv4:
    severity: info
  platform-reference:
    enabled: false
ignore:
  - vendor
  - "*.generated.ts"

Para uma só linha há um comentário que se põe nessa linha ou na de cima: // greenlight:ignore seguido do nome da regra. Sem o nome desliga todas as regras dessa linha. Mais vale escrevê-lo, assim as outras verificações continuam ligadas.

A linha
let host = "10.1.2.3" // greenlight:ignore hardcoded-ipv4

A verificação a cada versão

Com --exit-code o comando termina com um erro se encontrar um CRITICAL ou um HIGH, ou se uma das verificações tiver falhado: assim uma verificação feita a meio nunca passa por boa. Põe-no na CI, ou seja, as verificações automáticas que correm a cada push, por exemplo o GitHub Actions: uma versão com um problema grave para sozinha.

O comando
greenlight preflight . --exit-code

6. O que não vê

O Greenlight lê texto, nunca abre a app. Se no código houver um botão «Apagar conta» ligado a nada, vê a palavra, a regra passa, e a Apple rejeita-te na mesma quando lhe toca.

Depois há os falsos alarmes. O caso mais claro é o problema número 30 no GitHub deles: em apps sem publicidade nenhuma, a regra dos anúncios da Google dispara porque encontra «ads» dentro de palavras normais como loadSdk ou downloads. Dá um CRITICAL sem indicar o ficheiro e sugere acrescentar o pop-up ATT, que numa app que não rastreia é precisamente a coisa errada. Antes de corrigir, vê sempre o que está mesmo no teu código.

E o código que lê é só Swift, Objective-C, React Native e Expo. A nossa app é feita em Flutter: o código Dart ele não lê, por isso um login com a Google sem a Apple escrito em Dart passa-lhe ao lado. Lê, no entanto, o Info.plist, o manifesto de privacidade, o manifesto Android, os ficheiros Gradle e a app compilada. Em Flutter passa-lhe sempre os ficheiros compilados, e testa à mão o login e a eliminação da conta.

Dois comandos opcionais não são offline: o verify experimenta alguns fluxos num telemóvel na cloud e pede uma conta Revyl; o scan --app-id verifica a ficha no App Store Connect e pede login lá. Este guia não os usa.

Os erros mais comuns

  • Tomar GREENLIT por uma aprovação. Quer dizer que nos ficheiros não resta nada grave, não que a app funciona.
  • Corrigir um falso alarme. Antes de acrescentar o pop-up ATT ou mudar código, vê o que ele encontrou mesmo e onde.
  • Verificar só o código-fonte. As permissões que as bibliotecas acrescentam só se veem no ficheiro compilado: passa-lhe também o .ipa, .apk ou .aab.
  • Confiar no verde numa app Flutter. O Dart ele não lê: o login e a eliminação da conta testas tu, no telemóvel.

Checklist

  • Greenlight instalado, na versão mais recente
  • greenlight preflight . corrido na pasta principal do projeto
  • Verificação repetida com o ficheiro compilado: .ipa, .apk ou .aab
  • Zero CRITICAL e zero HIGH, ou cada um explicado
  • Cada falso alarme verificado à mão e registado no .greenlight.yml ou com greenlight:ignore
  • greenlight preflight . --exit-code na CI
  • Eliminação da conta, restaurar compras e início de sessão com a Apple testados na app real

Perguntas frequentes

O Greenlight manda o meu código para algum lado?

Não. O preflight e as outras verificações correm no teu computador, sem conta e sem rede. Só o verify e o scan vão à rede, e só os corres se quiseres.

Se passar, a Apple aprova-ma?

Não necessariamente. O Greenlight verifica os ficheiros, enquanto a Apple experimenta certos fluxos à mão. Tira os erros que se veem no texto; o resto testas tu na app real.

Preciso do Claude Code para o usar?

Não. É um programa de terminal e funciona sozinho. O plugin serve se quiseres que seja o Claude a correr a verificação, corrigir e voltar a correr.

← Todos os guias