Notification Payload es una estructura JSON que el servidor envía a través de APNS a un dispositivo iOS, definiendo el contenido de una notificación push y el comportamiento al recibirla. El payload incluye claves obligatorias y opcionales que controlan el texto, sonido, badge, adjuntos multimedia y procesamiento en segundo plano. Según Apple Developer Documentation, 2026, el tamaño máximo del payload es de 4096 bytes para notificaciones normales y 5120 bytes para VoIP push, imponiendo límites estrictos a la cantidad de datos transferidos.
Puntos Clave
Notification Payload es un objeto JSON que el servidor envía a APNS (Apple Push Notification Service) para su entrega a un dispositivo iOS. El payload contiene todos los datos que el sistema necesita para mostrar la notificación: título, texto, sonido, badge y metadatos para procesamiento en segundo plano. La estructura del payload está estrictamente regulada por Apple e incluye claves obligatorias para su correcto procesamiento por el sistema.
Cuando el servidor envía una notificación push a través de la API HTTP/2 de APNS, la solicitud contiene encabezados de autorización y un cuerpo JSON — el payload. APNS valida el payload: si el JSON es incorrecto o supera el límite de tamaño, el servidor de Apple devuelve un error 400 Bad Request. Tras la validación, APNS entrega el payload al dispositivo, donde iOS lo analiza y determina cómo manejar la notificación — mostrar un banner, ejecutar una tarea en segundo plano o reproducir un sonido.
El formato del payload APNS evolucionó desde un payload de texto simple en iOS 2 hasta una estructura JSON multicomponente en las versiones modernas. iOS 10 introdujo soporte para adjuntos multimedia mediante mutable-content, iOS 12 añadió agrupación de notificaciones mediante thread-id, e iOS 15 incorporó supports-live-activities para Live Activities. Hoy en día, un payload puede contener hasta 15 claves diferentes según el comportamiento deseado de la notificación.
El objeto raíz del payload contiene un diccionario aps y campos personalizados opcionales en el nivel superior. El diccionario aps es el único elemento obligatorio, pero dentro de él pueden aparecer diversas combinaciones de claves según el tipo de notificación: alert, badge, sound, content-available, mutable-content, interruption-level y otras.
| Clave aps | Tipo | Propósito |
|---|---|---|
| alert | String o Dictionary | Texto de la notificación u objeto con title, subtitle, body y localización |
| badge | Number | Número en el icono de la aplicación; 0 elimina el badge |
| sound | String | Nombre del archivo de sonido o default para el sonido del sistema |
| content-available | Number (1) | Indicador de activación en segundo plano; 1 = silent push |
| mutable-content | Number (1) | Indicador de activación de Service Extension para modificar contenido |
| category | String | Identificador de categoría para botones y Content Extension |
| thread-id | String | Identificador de grupo para agrupar notificaciones |
| interruption-level | String | Nivel de interrupción: passive, active, time-sensitive, critical |
| relevance-score | Number (0–1) | Prioridad de la notificación para el sistema de clasificación inteligente |
La clave alert puede ser una cadena simple (que se convierte en el cuerpo de la notificación) o un diccionario con los campos title, subtitle y body. El formato de diccionario permite establecer el título y subtítulo por separado del texto principal. Para notificaciones localizadas, se usan las claves title-loc-key, title-loc-args, loc-key y loc-args, que hacen referencia a los Localizable.strings de la aplicación. Esto permite enviar un payload sin texto en un idioma específico — la aplicación sustituye la traducción.
A partir de iOS 15, Apple introdujo el mecanismo Focus Mode, que requiere que el desarrollador especifique el nivel de interrupción de la notificación. interruption-level acepta los valores: passive (sin sonido, sin activar la pantalla), active (comportamiento estándar), time-sensitive (atraviesa Focus, requiere autorización especial) y critical (situaciones médicas/de emergencia). La clave relevance-score (0–1) ayuda al sistema Focus a clasificar notificaciones dentro de una misma categoría.
La clave thread-id agrupa notificaciones en el Centro de Notificaciones. Todas las notificaciones con el mismo thread-id se muestran como un único grupo que el usuario puede expandir. Esto es especialmente útil para mensajería, donde los mensajes de un mismo contacto se agrupan, o para aplicaciones que envían muchas notificaciones del mismo tipo.
Los campos personalizados son claves fuera del diccionario aps que el desarrollador añade para transmitir datos adicionales al dispositivo. El servidor los incluye en el objeto JSON raíz del payload, y la aplicación los obtiene a través de userInfo en UNNotificationContent. Los campos personalizados no deben duplicar nombres de claves de aps para evitar conflictos durante el análisis.
La limitación principal es que el tamaño total del payload no debe superar los 4096 bytes. Los campos personalizados compiten por este límite con las claves obligatorias de aps, por lo que es importante minimizar el tamaño de los datos transmitidos. Utilice nombres cortos para las claves (por ejemplo, “uid” en lugar de “user-id”), evite estructuras JSON grandes y transmita solo identificadores en lugar de objetos de datos completos.
Los campos personalizados provienen del servidor y no deben aceptarse sin verificación. Valide siempre los tipos y valores de los campos personalizados al analizarlos: compruebe la existencia de la clave mediante enlace opcional, convierta al tipo esperado con as? String/Int/Dictionary y maneje el caso de valor ausente. Nunca use force unwrap (!) para datos del payload — el servidor podría enviar datos inválidos y la aplicación se bloquearía.
{
"aps": {
"alert": {
"title": "Nuevo mensaje",
"body": "¡Hola! ¿Cómo estás?"
},
"badge": 5,
"sound": "default",
"category": "message",
"thread-id": "chat_4521",
"mutable-content": 1
},
"sender-id": "user_789",
"chat-id": "chat_4521",
"message-type": "text",
"image-url": "https://cdn.example.com/img.jpg"
}
Utilice un estilo de nomenclatura coherente para los campos personalizados en todos los payloads del proyecto. kebab-case (message-type) o camelCase (messageType) — ambos enfoques son aceptables, pero la coherencia dentro del proyecto es importante. Evite nombres largos: “uid” en lugar de “user-identifier”, “img” en lugar de “profile-image-url”. Cada carácter en un nombre de clave consume un byte del límite de 4096.
Diferentes escenarios de notificaciones push requieren diferentes combinaciones de claves en el payload. Veamos varios ejemplos típicos: una notificación de texto simple, una notificación localizada, un Silent Push y una Notificación Enriquecida con adjunto multimedia.
Un payload básico con texto y sonido — la configuración mínima para mostrar una notificación al usuario. Alert como cadena proporciona un mensaje corto, sound default reproduce el sonido del sistema estándar. Badge es opcional y establece el contador en el icono de la aplicación. category y thread-id se añaden para agrupación e interactividad.
{
"aps": {
"alert": "Recordatorio: reunión en 15 minutos",
"badge": 3,
"sound": "default"
}
}
Para enviar notificaciones a dispositivos con diferentes idiomas, utilice claves de localización en lugar de texto fijo. title-loc-key hace referencia a una clave en los Localizable.strings de la aplicación, y title-loc-args proporciona argumentos. Esto permite enviar un único payload a todos los dispositivos, y la aplicación muestra el texto en el idioma correspondiente.
{
"aps": {
"alert": {
"title-loc-key": "NEW_MESSAGE_TITLE",
"title-loc-args": ["Ana"],
"loc-key": "NEW_MESSAGE_BODY",
"loc-args": ["¡Hola!"]
},
"sound": "message.caf"
}
}
Para sincronización en segundo plano sin mostrar una notificación, use content-available: 1 sin alert. Los campos personalizados especifican el tipo de operación y los datos para procesar. El sistema activa la aplicación en segundo plano, llama a didReceiveRemoteNotification con fetchCompletionHandler, y la aplicación realiza la sincronización.
{
"aps": {
"content-available": 1
},
"sync-type": "invalidate-cache",
"timestamp": "2026-07-03T12:00:00Z"
}
Para mostrar un adjunto multimedia, se necesita mutable-content: 1 para activar la Service Extension, junto con una URL de imagen en un campo personalizado. mutable-content: 1 señala al sistema que debe lanzar UNNotificationServiceExtension, que descarga la imagen de la URL y la añade como UNNotificationAttachment. La clave category especifica una categoría registrada para mostrar botones de acción.
{
"aps": {
"alert": {
"title": "Nuevo producto",
"body": "Mira la nueva colección"
},
"category": "product",
"mutable-content": 1
},
"media-url": "https://cdn.example.com/product.jpg"
}
UNNotificationContent.userInfo contiene el diccionario completo del payload recibido tras el procesamiento del sistema. La aplicación accede al payload en el delegado de UNUserNotificationCenter al recibir una notificación (en primer plano), al tocar una notificación, así como en Service Extension y Content Extension. El análisis correcto es esencial para extraer datos personalizados y determinar las siguientes acciones.
Cuando el usuario toca una notificación, el sistema llama al método didReceive response en UNUserNotificationCenterDelegate. response.notification.request.content.userInfo contiene el payload completo. El desarrollador extrae los campos personalizados, determina el tipo de acción (por ejemplo, abrir un chat, navegar a un producto) y activa la navegación correspondiente en la aplicación.
func userNotificationCenter(
_ center: UNUserNotificationCenter,
didReceive response: UNNotificationResponse,
withCompletionHandler completionHandler: @escaping () -> Void
) {
let userInfo = response.notification
.request.content.userInfo
guard let chatId = userInfo["chat-id"] as? String
else {
completionHandler()
return
}
let messageType = userInfo["message-type"]
as? String ?? "text"
NavigationRouter.shared.navigate(
to: .chat(chatId: chatId,
messageType: messageType))
completionHandler()
}
La Service Extension recibe el payload antes de que se muestre la notificación y puede modificarlo. La validación del payload es el primer paso en didReceive: compruebe los campos personalizados obligatorios, valide la URL del adjunto y verifique los tipos de datos. Si el payload no es válido, llame al completion handler con el contenido original inmediatamente para no perder tiempo en procesamiento innecesario.
Para depurar notificaciones push en producción, utilice un registro estructurado de payloads. OSLog permite registrar el payload con la categoría “notifications” y nivel debug. En el lado del servidor, supervise las respuestas de APNS: una respuesta exitosa contiene apns-id para coincidir con el payload enviado, mientras que un error 400 indica JSON mal formado o superación del límite de tamaño.
Preguntas Frecuentes
El tamaño máximo del payload es 4096 bytes para notificaciones push normales y 5120 bytes para VoIP push (PushKit). Superar este límite hace que APNS devuelva un error 400 Bad Request. El tamaño se cuenta en bytes, no en caracteres — tenga en cuenta la codificación UTF-8.
Utilice las claves loc-key, title-loc-key, loc-args y title-loc-args dentro de alert. La aplicación sustituye la traducción de sus Localizable.strings según el idioma del dispositivo. Esto permite enviar un único payload a todos los dispositivos independientemente de su idioma.
content-available activa la aplicación en segundo plano para procesar datos (silent push) sin mostrar una notificación. mutable-content activa la Service Extension para modificar el contenido antes de mostrarlo. Ambas claves pueden usarse juntas para procesamiento en segundo plano y posterior modificación de la notificación.
Utilice APNS Sandbox para pruebas y compruebe la respuesta HTTP del servidor de Apple: 200 OK significa entrega exitosa. Para validación de estructura, use esquemas JSON en su pipeline de CI/CD. En Xcode, envíe notificaciones de prueba a través del simulador con xcrun simctl push.
apns-id es un identificador único de notificación push en el sistema APNS, devuelto en la respuesta tras una entrega exitosa. Se utiliza para rastrear la entrega a través de la API de Logs y para depuración. El servidor debe almacenar apns-id para cada notificación enviada.
Resumen
Desarrollaremos una aplicación móvil llave en mano
IT Sectr crea aplicaciones para iOS y Android para startups y empresas desde 2017. Le asesoraremos y le propondremos la mejor solución.
Lea también