# ITMS-90683: corregir “Missing purpose string” con Expo

> ITMS-90683 Missing purpose string: por qué Apple rechaza tu build, qué clave agregar en app.json con Expo y cómo detectar las claves que faltan antes del envío.

Página original: [ITMS-90683: corregir “Missing purpose string” con Expo](https://devoria.fr/es/blog/itms-90683-missing-purpose-string-expo)
Autor: [Mehdi Azizi](https://devoria.fr/es/mehdi-azizi)
Publicación: 2026-10-09
Última revisión del contenido: 2026-10-09


ITMS-90683 es un rechazo automático de Apple: llega por correo poco después de enviar tu build, antes de cualquier revisión humana. Significa que en tu archivo Info.plist falta la frase que explica por qué la app accede a un dato sensible. **La corrección son dos pasos: agregar a `ios.infoPlist` la clave que menciona el mensaje y luego hacer un nuevo build.**

Me pasó con Solys, mi despertador con minijuegos, por un dato que la app ni siquiera usa. Aquí te explico qué significa el mensaje, por qué aparece y cómo evitarlo.

## ¿Qué significa el error ITMS-90683?

El mensaje completo se titula "ITMS-90683: Missing purpose string in Info.plist". Dice que el código de tu app hace referencia a una API que toca datos sensibles (fotos, cámara, micrófono, ubicación, contactos) y que tu Info.plist no contiene la clave de descripción correspondiente. El mensaje nombra esa clave, por ejemplo `NSPhotoLibraryUsageDescription`.

Esa frase de descripción se llama "purpose string". Es el texto que iOS muestra en la ventana de solicitud de permiso. Apple lo dice en su documentación sobre el [acceso a recursos protegidos](https://developer.apple.com/documentation/uikit/requesting-access-to-protected-resources): App Review rechaza las apps cuyo código accede a estos recursos sin purpose string.

No es el rechazo de un revisor. El control es automático y ocurre al entregar el build, antes de pasar a revisión, igual que [ITMS-91053](https://devoria.fr/es/blog/itms-91053-missing-api-declaration-expo) para el manifiesto de privacidad. El build se descarta y tienes que enviar otro.

## Por qué Apple rechaza aunque tu app no use ese dato

Esto es lo que sorprende. **Apple analiza el código que contiene tu build, no lo que tu app hace realmente.** Si una librería que incluyes hace referencia a la fototeca, la clave es obligatoria, aunque ninguna pantalla pida nunca acceso a las fotos. El propio mensaje de Apple lo aclara: una librería o un SDK externo puede hacer referencia a estas API, y la purpose string sigue siendo obligatoria.

Mi caso, el 26 de septiembre de 2026. Limpiando la configuración de Solys, quité la clave `NSPhotoLibraryUsageDescription`, ya que la app no toca ninguna foto. El siguiente build fue rechazado con ITMS-90683. La causa: dos librerías de Expo que usa la app, `expo-image` y `expo-file-system`, contienen código que hace referencia a la fototeca. El build anterior pasaba porque la clave seguía ahí.

**La lección**: una clave de descripción no se quita "porque no la usamos". Solo se quita cuando ninguna librería del build hace ya referencia a la API.

## Las claves más comunes

- `NSPhotoLibraryUsageDescription`: lectura o escritura de fotos.
- `NSPhotoLibraryAddUsageDescription`: agregar fotos, sin lectura.
- `NSCameraUsageDescription`: cámara.
- `NSMicrophoneUsageDescription`: micrófono.
- `NSLocationWhenInUseUsageDescription`: ubicación durante el uso.
- `NSContactsUsageDescription`: contactos.
- `NSUserTrackingUsageDescription`: rastreo publicitario ([App Tracking Transparency](https://devoria.fr/es/blog/guideline-5-1-2-ia-terceros-att-datos-compartidos)).

Apple describe cada clave en su documentación, por ejemplo la de [NSPhotoLibraryUsageDescription](https://developer.apple.com/documentation/bundleresources/information-property-list/nsphotolibraryusagedescription): es obligatoria en cuanto la app usa una API que lee o escribe en la fototeca.

## Corregir ITMS-90683 en una app Expo

1. **Anota la clave que menciona el correo de Apple.** El mensaje da su nombre exacto.
2. **Agrégala a tu configuración**, dentro de `ios.infoPlist`, como indica la [documentación de Expo sobre permisos](https://docs.expo.dev/guides/permissions/):

```json
{
  "expo": {
    "ios": {
      "infoPlist": {
        "NSPhotoLibraryUsageDescription": "Solys no accede a tus fotos. Este permiso nunca se solicita."
      }
    }
  }
}
```

3. **Haz un nuevo build.** Expo lo aclara: un cambio en el Info.plist no se aplica con una actualización remota, requiere un nuevo binario.
4. **Vuelve a enviar el build** a Apple y luego selecciónalo en tu versión.

Una trampa si tu app está traducida: los archivos de idioma traducen una clave, no la declaran. La clave primero tiene que existir en `ios.infoPlist` (o en la configuración del plugin correspondiente). Si no, la app puede cerrarse en la primera llamada.

## ¿Qué frase escribir si tu app no usa el dato?

Apple pide una descripción exacta, útil y precisa. Si tu app realmente usa el dato, di para qué sirve, en una frase: "La app usa la cámara para escanear el código de barras de tu boleto."

Si la clave solo está ahí por una librería, Apple da dos soluciones: escribir la frase o quitar el código que accede al dato. Cuando ese código viene de una librería, no puedes quitarlo fácilmente. Así que en Solys escribí la verdad: "Solys no accede a tus fotos. Este permiso nunca se solicita." Es una decisión pragmática: el siguiente build pasó la entrega, pero no puedo asegurarte que Apple vaya a aceptar siempre esta frase.

## Detectar las claves que faltan antes del envío

Desde la raíz de tu proyecto, este comando lista los archivos de las librerías cuyo código iOS hace referencia a las API más vigiladas:

```bash
grep -rlE "PHPhotoLibrary|AVCaptureDevice|CLLocationManager|CNContactStore|EKEventStore|ATTrackingManager" \
  node_modules/*/ios node_modules/@*/*/ios
```

Cada nombre corresponde a un dato: `PHPhotoLibrary` para las fotos, `AVCaptureDevice` para la cámara y el micrófono, `CLLocationManager` para la ubicación, `CNContactStore` para los contactos, `EKEventStore` para el calendario, `ATTrackingManager` para el rastreo. Para cada resultado, verifica que la clave de descripción correspondiente exista en tu configuración.

Este filtro atrapa los casos que me he encontrado. No reemplaza la lectura del correo de Apple, que sigue siendo la única lista confiable, igual que con las API no públicas de ITMS-90338. Desde ese rechazo, hago esta verificación antes de cada build: toma unos segundos, mientras que un rechazo ITMS-90683 cuesta un build y el tiempo de rehacerlo.

## Enviar tu build sin sorpresas

ITMS-90683 se corrige rápido cuando sabes leerlo, igual que ITMS-90725, que tiene que ver con la versión de Xcode. Los rechazos que vienen después, los de un revisor, requieren más perspectiva: el proceso está en la página [app rechazada por Apple](https://devoria.fr/es/expertise/app-rechazada-por-apple), y los motivos más frecuentes están en [por qué Apple rechaza una app](https://devoria.fr/es/blog/rechazo-apple-por-que-rechazan-tu-app).

Para revisar todo antes del envío, el [Apple Review Kit](https://devoria.fr/es/kits/review-apple) reúne mi checklist y skills de Claude Code que revisan tu proyecto. Si tu envío está bloqueado y quieres una mirada humana, [reserva una hora conmigo](https://devoria.fr/es/coaching): revisamos tu proyecto por videollamada, en tu pantalla. Y si estás preparando tu primer lanzamiento, [haz tu diagnóstico gratuito](https://devoria.fr/es/diagnostic): ordena los pasos y te envía mi checklist contra rechazos de Apple.

## Preguntas frecuentes

### ¿ITMS-90683 es un rechazo de App Review?

No en el sentido de un revisor humano. Es un control automático que se hace sobre el build al entregarlo, antes de pasar a revisión, igual que ITMS-90717 para el ícono. Nadie abrió tu app. El build se descarta: tienes que corregir el Info.plist y enviar uno nuevo.

### ¿Por qué Apple pide una clave para un dato que mi app no usa?

Porque Apple analiza el código presente en el build, no el comportamiento de la app. Si una librería incluida hace referencia a la fototeca o a la cámara, la clave de descripción es obligatoria, aunque ninguna pantalla pida nunca ese acceso.

### ¿Se puede corregir ITMS-90683 con una actualización remota?

No. La clave que falta está en el Info.plist, que forma parte del binario. Una actualización remota no modifica ese archivo: tienes que hacer un nuevo build y enviarlo a Apple.

### ¿Dónde agregar NSPhotoLibraryUsageDescription en un proyecto Expo?

En la configuración de tu app, dentro de `ios.infoPlist`, con una frase que describa el uso. Algunas librerías también ofrecen un ajuste propio en su plugin, que puede agregar otras claves, como un modo en segundo plano. En ambos casos, la clave tiene que existir en la configuración base, no solo en los archivos de traducción.

### ¿Hay que quitar las claves de descripción que no se usan?

Solo si ninguna librería del build hace ya referencia a la API correspondiente. Si no, el siguiente envío será rechazado con ITMS-90683. Antes de quitar una clave, busca el nombre de la API en el código iOS de tus dependencias.


## Tu proyecto

[Apple Review Kit](https://devoria.fr/es/kits/review-apple): La checklist de revisión del App Store que uso, mis rechazos de Apple corregidos, las notas para el revisor y dos skills de Claude Code que revisan tu app. 29 €.

[iOS Kit](https://devoria.fr/es/kits/ios): Crea tu app para iPhone con Claude Code: el código base de mis apps, los skills que verifican su trabajo y los kits Apple Review, App Store Screenshots y ASO. 129,99 €.
