ITMS-90683: corrigir “Missing purpose string” no Expo
Por Mehdi Azizi
Publicado em , 6 min
ITMS-90683 Missing purpose string: por que a Apple recusa seu build, qual chave adicionar no app.json com Expo e como achar as chaves faltando antes do envio.
ITMS-90683 é uma recusa automática da Apple: chega por e-mail logo depois do envio do seu build, antes de qualquer revisão humana. Significa que está faltando, no seu arquivo Info.plist, a frase que explica por que o app acessa um dado sensível. A correção se resume a dois passos: adicionar a chave citada na mensagem em ios.infoPlist e fazer um novo build.
Levei essa no Solys, meu despertador com minijogos, por causa de um dado que o app nem usa. Veja o que a mensagem quer dizer, por que ela aparece e como evitá-la.
O que significa o erro ITMS-90683?
A mensagem completa se chama "ITMS-90683: Missing purpose string in Info.plist". Ela diz que o código do seu app faz referência a uma API que mexe com dados sensíveis (fotos, câmera, microfone, localização, contatos) e que o seu Info.plist não tem a chave de descrição correspondente. A mensagem informa o nome dessa chave, por exemplo NSPhotoLibraryUsageDescription.
Essa frase de descrição se chama "purpose string". É o texto que o iOS mostra na janela de pedido de permissão. A Apple escreve isso na documentação sobre acesso a recursos protegidos: o App Review recusa apps cujo código acessa esses recursos sem purpose string.
Não é a recusa de um revisor. A checagem é automática e acontece na entrega do build, antes de ele entrar em revisão, como o ITMS-91053 para o manifesto de privacidade. O build é descartado e você precisa enviar outro.
Por que a Apple recusa mesmo que seu app não use esse dado
Esse é o ponto que pega todo mundo de surpresa. A Apple analisa o código que está no seu build, não o que o seu app faz de verdade. Se uma biblioteca que você inclui tem uma referência à fototeca, a chave é exigida, mesmo que nenhuma tela peça acesso às fotos. A própria mensagem da Apple deixa isso claro: uma biblioteca ou SDK externo pode fazer referência a essas APIs, e a purpose string continua obrigatória.
Meu caso, em 26 de setembro de 2026. Limpando a configuração do Solys, eu tinha removido a chave NSPhotoLibraryUsageDescription, já que o app não mexe em nenhuma foto. O build seguinte foi recusado com ITMS-90683. O motivo: duas bibliotecas do Expo que o app usa, expo-image e expo-file-system, têm código que faz referência à fototeca. O build anterior passava porque a chave ainda estava lá.
A lição: uma chave de descrição não se remove "porque não está sendo usada". Ela só pode sair quando nenhuma biblioteca do build fizer mais referência à API.
As chaves mais comuns
NSPhotoLibraryUsageDescription: leitura ou gravação de fotos.NSPhotoLibraryAddUsageDescription: adição de fotos, sem leitura.NSCameraUsageDescription: câmera.NSMicrophoneUsageDescription: microfone.NSLocationWhenInUseUsageDescription: localização durante o uso.NSContactsUsageDescription: contatos.NSUserTrackingUsageDescription: rastreamento publicitário (App Tracking Transparency).
A Apple descreve cada chave na documentação, por exemplo a de NSPhotoLibraryUsageDescription: ela é exigida assim que o app usa uma API que lê ou grava na fototeca.
Corrigir o ITMS-90683 em um app Expo
- Anote a chave citada no e-mail da Apple. A mensagem traz o nome exato.
- Adicione-a na sua configuração, em
ios.infoPlist, como indica a documentação do Expo sobre permissões:
{
"expo": {
"ios": {
"infoPlist": {
"NSPhotoLibraryUsageDescription": "O Solys não acessa suas fotos. Essa permissão nunca é solicitada."
}
}
}
}
- Faça um novo build. O Expo deixa claro: uma mudança no Info.plist não vai por atualização remota, ela exige um novo binário.
- Reenvie o build para a Apple e depois selecione-o na sua versão.
Uma armadilha se o seu app é traduzido: os arquivos de idioma traduzem uma chave, eles não a declaram. A chave precisa existir primeiro em ios.infoPlist (ou na configuração do plugin correspondente). Caso contrário, o app pode travar na primeira chamada.
Que frase escrever se o seu app não usa o dado?
A Apple pede uma descrição exata, útil e precisa. Se o seu app realmente usa o dado, diga para que serve, em uma frase: "O app usa a câmera para escanear o código de barras do seu ingresso."
Se a chave só está ali por causa de uma biblioteca, a Apple oferece duas soluções: escrever a frase ou remover o código que acessa o dado. Quando esse código vem de uma biblioteca, você não consegue simplesmente removê-lo. No Solys, então, escrevi a verdade: "O Solys não acessa suas fotos. Essa permissão nunca é solicitada." É uma escolha pragmática: o build seguinte passou na entrega, mas não posso garantir que a Apple sempre vai aceitar essa frase.
Achar as chaves faltando antes do envio
Na raiz do seu projeto, este comando lista os arquivos das bibliotecas cujo código iOS faz referência às APIs mais vigiadas:
grep -rlE "PHPhotoLibrary|AVCaptureDevice|CLLocationManager|CNContactStore|EKEventStore|ATTrackingManager" \
node_modules/*/ios node_modules/@*/*/ios
Cada nome corresponde a um dado: PHPhotoLibrary para fotos, AVCaptureDevice para câmera e microfone, CLLocationManager para localização, CNContactStore para contatos, EKEventStore para calendário, ATTrackingManager para rastreamento. Para cada resultado, confira se a chave de descrição correspondente existe na sua configuração.
Essa rede pega os casos que eu encontrei. Ela não substitui a leitura do e-mail da Apple, que continua sendo a única lista confiável, como para as APIs não públicas do ITMS-90338. Desde essa recusa, faço essa checagem antes de cada build: leva alguns segundos, enquanto uma recusa ITMS-90683 custa um build e o tempo de refazê-lo.
Enviar seu build sem surpresas
O ITMS-90683 se corrige rápido quando você sabe ler a mensagem, assim como o ITMS-90725, que trata da versão do Xcode. As recusas que vêm depois, as de um revisor, pedem mais calma: o passo a passo está na página app recusado pela Apple, e os motivos mais frequentes estão em por que a Apple recusa um app.
Para conferir tudo antes do envio, o Apple Review Kit reúne meu checklist e skills do Claude Code que revisam o seu projeto. Se o seu envio travou e você quer um olhar humano, reserve uma hora comigo: a gente revisa seu projeto por videochamada, na sua tela. E se você está preparando seu primeiro lançamento, faça seu diagnóstico gratuito: ele coloca as etapas na ordem certa e te envia meu checklist anti-recusa da Apple.
Perguntas frequentes
O ITMS-90683 é uma recusa do App Review?
Não no sentido de um revisor humano. É uma checagem automática feita no build na entrega, antes de entrar em revisão, como o ITMS-90717 para o ícone. Ninguém abriu o seu app. O build é descartado: você precisa corrigir o Info.plist e enviar um novo.
Por que a Apple pede uma chave para um dado que meu app não usa?
Porque a Apple analisa o código presente no build, não o comportamento do app. Se uma biblioteca incluída faz referência à fototeca ou à câmera, a chave de descrição é exigida, mesmo que nenhuma tela peça esse acesso.
Dá para corrigir o ITMS-90683 com uma atualização remota?
Não. A chave que falta fica no Info.plist, que faz parte do binário. Uma atualização remota não altera esse arquivo: você precisa fazer um novo build e reenviá-lo para a Apple.
Onde adicionar NSPhotoLibraryUsageDescription em um projeto Expo?
Na configuração do app, em ios.infoPlist, com uma frase que descreva o uso. Algumas bibliotecas também oferecem uma opção própria no plugin, que pode adicionar outras chaves, como um modo em segundo plano. Nos dois casos, a chave precisa existir na configuração base, não só nos arquivos de tradução.
Devo remover as chaves de descrição que não uso?
Só se nenhuma biblioteca do build fizer mais referência à API em questão. Caso contrário, o próximo envio será recusado com ITMS-90683. Antes de remover uma chave, procure o nome da API no código iOS das suas dependências.