Privacy Manifests en iOS: qué declarar antes de publicar una app
Arturo Rivas Arias
🔐 Una aplicación puede comportarse de forma respetuosa con la privacidad y, aun así, resultar difícil de auditar. El código propio es solo una parte del producto: las bibliotecas de analítica, autenticación, red, imágenes o informes de errores también pueden recopilar información o consultar señales del dispositivo. Los Privacy Manifests convierten parte de ese comportamiento en una declaración legible tanto para Xcode como para App Store Connect.
📄 El manifiesto es un archivo de propiedades llamado PrivacyInfo.xcprivacy. No solicita permisos, no bloquea llamadas y tampoco modifica lo que ocurre durante la ejecución. Su función es describir las prácticas de privacidad de la app o del SDK que lo incluye: qué datos recopila, para qué los utiliza, si están vinculados con la identidad, si intervienen en seguimiento y qué categorías de API de motivo obligatorio consulta.
🧭 Por tanto, no sustituye a los mensajes de uso de Info.plist, a App Tracking Transparency ni a la ficha de privacidad de la App Store. Son piezas relacionadas, pero distintas. NSCameraUsageDescription, por ejemplo, explica al usuario por qué aparece una petición del sistema; el manifiesto describe prácticas del binario; la ficha de privacidad comunica esas prácticas en la tienda; y ATT regula determinados usos de datos para seguir a una persona entre aplicaciones y sitios web.
Las cuatro partes del manifiesto
🧱 Un PrivacyInfo.xcprivacy puede contener cuatro bloques principales. NSPrivacyCollectedDataTypes declara las categorías de datos recopilados. NSPrivacyTracking indica si existe seguimiento. NSPrivacyTrackingDomains enumera los dominios relacionados con ese seguimiento. Por último, NSPrivacyAccessedAPITypes recoge las API de motivo obligatorio y los códigos que justifican su uso.
📦 Cada app y cada SDK deben describir su propio comportamiento. El manifiesto del ejecutable principal no debe utilizarse para encubrir o completar las declaraciones que corresponden a una dependencia. Cuando se archiva la aplicación, Xcode agrega los manifiestos incluidos en sus distintos bundles y puede generar un informe conjunto. De esta forma se conserva la responsabilidad de cada componente sin perder una visión global del producto distribuido.
Qué significa realmente recopilar datos
📤 En este contexto, recopilar implica transmitir datos fuera del dispositivo de manera que el desarrollador o un tercero puedan acceder a ellos durante un periodo superior al necesario para atender la petición en tiempo real. Que una app acceda localmente a una fotografía, a una grabación o a una ubicación no significa automáticamente que la esté recopilando. Si esa información se envía a un servidor y queda disponible allí, la situación cambia.
🗂️ Por cada categoría recopilada hay que indicar cuatro elementos: el tipo de dato, si queda vinculado a la identidad de la persona, si se utiliza para seguimiento y sus finalidades. Entre las finalidades admitidas se encuentran la funcionalidad de la app, la personalización del producto, las analíticas, la publicidad del desarrollador, la publicidad de terceros…
🎙️ Imaginemos una aplicación de notas de voz que sincroniza las grabaciones con una cuenta privada. Un fragmento simplificado de su manifiesto podría ser el siguiente:
<plist version="1.0">
<dict>
<key>NSPrivacyTracking</key>
<false/>
<key>NSPrivacyCollectedDataTypes</key>
<array>
<dict>
<key>NSPrivacyCollectedDataType</key>
<string>NSPrivacyCollectedDataTypeAudioData</string>
<key>NSPrivacyCollectedDataTypeLinked</key>
<true/>
<key>NSPrivacyCollectedDataTypeTracking</key>
<false/>
<key>NSPrivacyCollectedDataTypePurposes</key>
<array>
<string>NSPrivacyCollectedDataTypePurposeAppFunctionality</string>
</array>
</dict>
</array>
</dict>
</plist>
🧩 La declaración indica que el audio llega a un servicio asociado con la cuenta, se utiliza para proporcionar la sincronización y no se emplea para seguimiento. Si las grabaciones nunca abandonasen el dispositivo, este bloque de datos recopilados podría no ser necesario. La decisión debe partir del flujo real de información, no del nombre del framework ni del permiso solicitado.
Las API de motivo obligatorio
🕵️ Algunas API aparentemente inocuas exponen señales que, combinadas, podrían servir para crear una huella del dispositivo. Apple agrupa esas llamadas en categorías de Required Reason APIs: marcas temporales de archivos, tiempo desde el arranque, espacio disponible en disco, teclados activos y preferencias almacenadas con UserDefaults.
🚫 La huella digital está prohibida incluso cuando el usuario haya autorizado el seguimiento. Declarar una categoría no convierte cualquier uso en válido. El código debe ajustarse a uno de los motivos aprobados por Apple y el manifiesto debe contener el código exacto correspondiente. Tampoco conviene declarar todas las categorías “por si acaso”: una declaración excesiva es tan poco fiable como una incompleta.
💾 En la app de notas de voz tendría sentido comprobar el espacio disponible antes de iniciar una grabación larga. La implementación podría consultar la capacidad reservada para operaciones importantes:
import Foundation
enum RecordingStorage {
static func hasCapacity(forEstimatedBytes bytes: Int64) throws -> Bool {
let values = try URL.documentsDirectory.resourceValues(
forKeys: [.volumeAvailableCapacityForImportantUsageKey]
)
guard let available = values.volumeAvailableCapacityForImportantUsage else {
return false
}
return available > bytes
}
}
🧾 Esa consulta pertenece a la categoría de espacio en disco. Si se utiliza únicamente para comprobar que existe capacidad suficiente antes de escribir la grabación, el manifiesto debe declarar la categoría y el motivo aprobado que representa ese caso:
<key>NSPrivacyAccessedAPITypes</key>
<array>
<dict>
<key>NSPrivacyAccessedAPIType</key>
<string>NSPrivacyAccessedAPICategoryDiskSpace</string>
<key>NSPrivacyAccessedAPITypeReasons</key>
<array>
<string>E174.1</string>
</array>
</dict>
</array>
⚠️ Los códigos no son descripciones libres. Hay que elegirlos en la documentación vigente de Apple y revisar sus condiciones completas, porque dos usos de una misma API pueden necesitar motivos diferentes. Además, la obligación alcanza al código compilado dentro de una dependencia. Que nuestra capa Swift no invoque directamente una API no demuestra que el binario final tampoco lo haga.
Dependencias y cadena de suministro
🧰 Los SDK de terceros son uno de los objetivos principales de este sistema. Apple mantiene una lista de dependencias muy utilizadas para las que exige un manifiesto, y también una firma cuando se distribuyen como binarios en los supuestos indicados. La lista incluye proyectos habituales de red, autenticación, analítica, bases de datos, imágenes e interfaces, por lo que una actualización rutinaria de paquetes puede afectar al envío a la tienda de aplicaciones.
✍️ La firma de un SDK y su manifiesto resuelven problemas distintos. La firma permite a Xcode comprobar que una nueva versión binaria procede del mismo desarrollador, reforzando la integridad de la cadena de suministro. El manifiesto explica sus prácticas declaradas de privacidad. Una firma válida no garantiza que las declaraciones sean correctas, y un manifiesto correcto no demuestra por sí solo el origen del binario.
🔄 Antes de publicar conviene actualizar las dependencias, revisar sus notas de versión y confirmar que cada bundle contiene un PrivacyInfo.xcprivacy válido. Si App Store Connect señala un manifiesto inválido dentro de un SDK, la solución adecuada suele ser adoptar una versión corregida o contactar con el proveedor o con su responsable. Copiar sus declaraciones al manifiesto de la app puede ocultar el síntoma, pero no corrige el paquete defectuoso ni la atribución de responsabilidades.
Seguimiento y dominios
🌐 Cuando la app o un SDK contactan con dominios utilizados para seguimiento, el manifiesto debe activar NSPrivacyTracking y enumerarlos en NSPrivacyTrackingDomains. Los valores son dominios o subdominios, sin protocolo, ruta, consulta ni barra final. Si NSPrivacyTracking es false, la lista de dominios de seguimiento no debe contener elementos.
🛑 En plataformas compatibles, el sistema puede bloquear conexiones hacia los dominios declarados cuando no existe autorización de seguimiento. Esta medida ayuda a evitar comunicaciones accidentales, pero no sustituye un diseño correcto. Utilizar otro dominio, un proxy o una ruta no declarada para eludir la decisión del usuario seguiría incumpliendo la política.
Cómo añadirlo y comprobarlo en Xcode
🛠️ Xcode incluye la plantilla App Privacy al crear un archivo nuevo. El resultado debe llamarse PrivacyInfo.xcprivacy y pertenecer al target cuyo comportamiento describe. En iOS, iPadOS, watchOS, tvOS y visionOS se incorpora en la raíz del bundle de la app; en macOS y Mac Catalyst se sitúa dentro de Contents/Resources. Si el proyecto usa Xcode, el sistema de compilación se encarga de esa ubicación al añadirlo correctamente a los recursos del target.
✅ El editor visual evita muchos errores de formato, aunque también permite mostrar las claves y los valores sin traducir. Esto resulta útil para comparar el archivo con la documentación. Un manifiesto es una lista de propiedades estricta: una clave inventada, un tipo incorrecto, un array vacío donde no está permitido o un código desconocido puede provocar que App Store Connect rechace el envío.
📋 La validación debería formar parte del proceso de entrega y no ser una tarea de última hora. Una revisión práctica puede seguir estos pasos:
- Inventariar las rutas por las que los datos salen del dispositivo y quién los recibe.
- Revisar las API de motivo obligatorio usadas por el código propio y por las dependencias.
- Confirmar que cada manifiesto está incluido en el target y en el bundle que le corresponde.
- Archivar la app y, desde Organizer, abrir el menú contextual del archivo y elegir Generate Privacy Report.
- Comparar el informe agregado con la ficha de privacidad configurada en App Store Connect.
- Repetir la auditoría después de cambios en analítica, publicidad, red, almacenamiento o paquetes externos.
🔎 El informe de privacidad generado por Xcode resume los datos declarados por la app y sus SDK. Es una ayuda para construir una ficha de privacidad coherente, no una prueba automática de que las declaraciones reflejan todo el comportamiento. Xcode solo puede agregar lo que cada manifiesto afirma; detectar una recopilación omitida sigue requiriendo conocer el código, la configuración remota y los servicios que reciben los datos.
🧪 También es posible validar la sintaxis del archivo con plutil -lint PrivacyInfo.xcprivacy. Obtener un resultado correcto solo confirma que el documento es un plist bien formado. Todavía puede contener categorías, estructuras o motivos que App Store Connect no acepte, de modo que la comprobación final debe incluir el informe de Xcode y las reglas actuales de Apple.
Errores habituales
🚨 El primer error consiste en confundir acceso con recopilación. Leer una preferencia local puede requerir un motivo aprobado aunque no se envíe ningún dato, mientras que la sección de datos recopilados depende de que la información salga del dispositivo bajo la definición de Apple. Son dos análisis independientes.
🧯 El segundo es declarar el uso potencial de una biblioteca en lugar de su configuración efectiva. Un SDK puede ofrecer publicidad, analítica y autenticación, pero la integración concreta quizá solo active una parte. El manifiesto proporcionado por el SDK debe reflejar lo que su código puede hacer en el producto distribuido, y la ficha de la tienda debe cubrir todos los usos que realmente puede realizar la app, incluso si algunas funciones son opcionales para cada persona.
🪪 El tercero es pensar que el permiso del usuario legaliza el fingerprinting. ATT autoriza determinados escenarios de seguimiento, no la creación de una huella mediante señales del sistema. Los motivos aprobados limitan la finalidad de las API sensibles independientemente del estado de autorización.
📅 El cuarto es tratar el manifiesto como un documento que se escribe una sola vez. Añadir un SDK de errores, cambiar el proveedor de analítica, introducir sincronización o comenzar a enviar nuevos campos al servidor puede volver obsoletas las declaraciones. El manifiesto forma parte de la arquitectura y debe evolucionar con el código.
🏁 Los Privacy Manifests no garantizan por sí solos la privacidad, pero crean un contrato verificable entre el código, sus dependencias y la información publicada en la App Store. Mantener ese contrato exige conocer los flujos de datos, limitar las API sensibles a motivos legítimos, exigir declaraciones correctas a los SDK y revisar el informe agregado en cada entrega. Cuando este trabajo se integra en el desarrollo habitual, deja de ser un trámite de publicación y se convierte en una herramienta de diseño y control de la cadena de suministro.