Guía tutorial: Notificaciones push en iOS Rich Notifications

| Última modificación: 14 de marzo de 2024 | Tiempo de Lectura: 6 minutos

Algunos de nuestros reconocimientos:

Premios KeepCoding
Ya hace unos años desde que Apple presentó iOS 10 en la WWDC 2016. En esta conferencia presentó además una de las grandes novedades que potenciaron enormemente el uso de la notificaciones push: las rich notifications (o notificaciones enriquecidas). En este tutorial, se enseñará cómo poder enviar notificaciones push con imágenes, videos o gifs haciendo uso de esta nueva funcionalidad. En este artículo no se pretende mostrar cómo configurar tu aplicación para poder recibir notificaciones push sino como añadir valor a las mismas, por lo que se dará por hecho que ya tu aplicación está lista para recibir notificaciones.

Notification Service Extension

Con la finalidad de poder generar notificaciones enriquecidas, Apple puso a disponibilidad de los desarrolladores una extensión para las aplicaciones de iOS denominada Notification Service Extension . Este tipo de extensiones generan un nuevo target para la aplicación el cual añade nueva funcionalidad a la misma. Esta es la forma en la que funcionaban las aplicaciones en la primera versión de watchOS, por ejemplo. Bueno… después de esta pequeña introducción… ¡manos al lío! El primer paso es añadir este nuevo target a nuestra aplicación. Para ello vamos a nuestro File -> New -> Target y se nos abrirá la siguiente ventana:
iOS Rich Notifications
En esta ventana debemos seleccionar la opción que aparece marcada: Notification Service Extension. Seguidamente nos aparecerá una ventana donde debemos introducir el nombre que le queremos dar al target y presionamos “Finish”. Una vez creado, nos aparecerá la siguiente ventana preguntándonos si queremos activar el scheme para dicho target. Seleccionamos “activate” y ¡listo!, ya estamos más cerca de tener notificaciones con imágenes, gifs y videos. captura-activate-test-scheme
Si nos fijamos ahora en el explorador del proyecto, vemos como se nos ha creado un nuevo grupo con el nombre que le dimos al target y que en su interior encontramos un fichero Swift con el nombre Notification Service . Esta clase es la encargada de modificar las notificaciones entrantes para añadirles el contenido que hayamos indicado. Si abrimos el fichero, vemos que contiene 2 propiedades y dos métodos. captura-ejemplo-codigo
La primera propiedad es un bloque que recibe como parámetro una instancia de tipo UNNotificationContent . Este bloque es el encargado de procesar la notificación modificada para que se muestre en el dispositivo.
La segunda propiedad es una variable de tipo UNMutableNotificationContent. Esta variable es la que utilizaremos para modificar el contenido y pasárselo al bloque mencionado anteriormente para que procese la notificación. El primer método que encontramos se llama didReceive(_:withContentHandler:). Este método se ejecuta cuando se recibe la notificación y es dónde debemos modificarla para posteriormente cederla al contentHandler y que la procese. En este método es donde incluiremos la lógica que modifica la notificación. El segundo método que encontramos se llama serviceExtensionTimeWillExpire. La importancia de este método viene dada por la restricción temporal que tiene la modificación de las notificaciones. Concretamente, contamos con 30 segundos como máximo para modificarla. En el caso de que nuestro método didReceive tarde demasiado tiempo en ceder la notificación modificada al contentHandler, el sistema ejecutará este método para darnos una última oportunidad de modificarla. En el caso de que superemos el tiempo, el sistema mostrará la notificación con su contenido original, así que tranquilos amigos, no se romperá nada. Ya que hemos terminado de explicar un poco el contenido de este fichero, vamos a entrar en materia y codificar la lógica necesaria para poder añadir a nuestras notificaciones gifs, imágenes en formato png o jpg y videos en formato mp4. El primer paso, es adaptar el json de las notificaciones para que nos permita modificar la notificación. Esta es la estructura que tiene una notificación básica:
{ "aps":{

          "alert":"Testing.. (0)", 

          "badge":1, 

          "sound":"default"

     }

}
Para que podamos ser capaces de modificar la notificación, debemos realizar dos cambios. El primer es modificar la estructura del alert , cuyo valor debe ser un json o diccionario con las claves “title” y “body”, cuyos valores serán el título y mensaje de la notificación respectivamente. El segundo es añadir una nueva key llamada “mutable-content” cuyo valor debe ser 1. Este último es el que habilita la modificación de la notificación recibida. Tras aplicar los cambios la notificación anterior quedaría así:
{"aps":{
        "alert": {
             "title":"Testing...(0)",
             "body":"Mensaje de prueba" 
       },
        "badge":1, 
        "sound":"default",
        "mutable-content":1 
      }
}
Estos cambios harán que la notificación una vez recibida pase por el método didReceive mencionado anteriormente. Pero… Quizás falta algo ¿no? Quizás te estés preguntando: ¿pero y la imagen? ¿y el video? ¿y el gifs? ¿de donde lo saco? Muy buena pregunta… Y la respuesta es que tenemos que añadir algo más al json anterior. Para poder obtener el contenido que queremos añadir, debemos pasar una URL del mismo en la notificación. Esta url debe ir como valor de una key que puede ser la que queramos y que debe ir al nivel del aps . En este ejemplo vamos a coger “attached” como key:
{
      "aps": {

           "alert": { 

                "title":"Testing...(0)",

                "body":"Mensaje de prueba"
           },
           "badge":1, 
           "sound":"default",
           "mutable-content":1
      },
      "attached":"https://cdn.pixabay.com/photo/2013/07/18/20/24/cheese-164872_1280.jpg"

}
Como se puede observar en este ejemplo, hemos elegido una url de una imagen jpg de pixabay para mostrarla en la notificación. Una vez hechas todas las modificaciones necesarias en el json de la notificación, el siguiente paso es codificar la lógica necesaria para modificarla una vez la recibamos en nuestra aplicación. Como ya hemos mencionado, toda la lógica encargada de modificar la notificación va dentro del método didReceive(_:withContentHandler:). Es importante mencionar que todo el código irá dentro de la sentencia
if let bestAttemptContent = bestAttemptContent { 

       // Todo aquí dentro

}
Lo primero que tenemos que hacer es obtener del json de la notificación la url del contenido que queremos mostrar y generar un instancia de URL a partir del mismo:
let attachedString = bestAttemptContent.userInfo["attached"] as? 
String
let attachedURL = URL(string: attachedString)

Obviamente, el resto de la lógica depende de que esto funcione correctamente, por lo que sólo seguiremos con la ejecución en caso de que nada falle:

if let attachedString = bestAttemptContent.userInfo["attached"] 

as? String, let attachedURL = URL(string: attachedString) {

      // Resto de la lógica aquí }

Una vez hemos logrado obtener la URL de la imagen, video o gif, debemos descargarla para ello, debemos crear una URLSession que utilizaremos para generar una tarea de descarga y ejecutarla.

let session = URLSession(configuration: 

URLSessionConfiguration.default)

let downloadTask = session.downloadTask(with: attachedURL) { (url, 

response, error) in

          // bloque donde obtenemos la imagen y la añadimos a la 

notificación

}

downloadTask.resume()
Finalmente, debemos rellenar el bloque de código que ejecuta la tarea de descarga creada. En este bloque debemos realizar los siguientes pasos:
  1. Comprobar si se ha dado un error. En caso afirmativo imprimir el mismo devolver una excepción o lo que queramos.
  2. En caso de que no haya habido error, debemos obtener el contenido a partir de la url donde se ha almacenado localmente y añadirla al bestAttemptContent .
  3. Finalmente, debemos pasarle la notificación ya modificada (el bestAttemptContent ) al contentHandler para que se procesada y se muestre al usuario.
// Paso 1
if let error = error {
     print("Error downloading: \(error.localizedDescription)") 
} else {

     // Paso 2
     let content: UNNotificationAttachment?

     // instanciar “content” 
     ...

     if let content = content {
      bestAttemptContent.attachments = [content] 
    }
}
// Paso 3
 contentHandler(bestAttemptContent)

Como podemos observar hemos dejado un hueco justo despues de la declaración de content . En este hueco es donde debemos genera a partir de la url del archivo descargado una instancia de UNNotificationMutableContent , de forma que el archivo pueda ser añadido a los attachements de la notificación. La lógica del mismo sería:

        let suffix = attachedURL.absoluteString.suffix(3)

        // obtenemos los 3 últimos caracteres de la url que corresponden al

 formato del archivo

       switch suffix { 

       case "mp4":

                 content = try! UNNotificationAttachment(identifier: 
 
                 attachedString, url: url, options:

                 [UNNotificationAttachmentOptionsTypeHintKey:kUTTypeMPEG4] 

                           break

                   case “jpg”:
                              content = try! UNNotificationAttachment(identifier:

                 attachmentString, url: url, options: 

                 [UNNotificationAttachmentOptionsTypeHintKey:kUTTypeJPEG])

                     break 

              case “gif”:

              content = try! UNNotificationAttachment(identifier: 

attachmentString, url: url, options: 

[UNNotificationAttachmentOptionsTypeHintKey:kUTTypeGIF])

                    break 

           case “png”:

            content = try! UNNotificationAttachment(identifier: 

attachmentString, url: url, options:

 [UNNotificationAttachmentOptionsTypeHintKey:kUTTypePNG])

                    break 

          default:

                    content = nil

                     print("Not a compatible extension" 

            }
Si miramos el código, vemos que a la hora de instanciar el attachement, debemos pasarle en el parámetro options el tipo de dato que vamos a mostrar. Existen muchos tipos de datos más admitidos además de estos cuatro, sientente libre de explorarlos y enviar notificaciones con ficheros mp3 o html adjuntos. Pues ya estamos listos. Si juntamos todo, nuestro método didReceive quedaría así:
Y ya podríamos enviar notificaciones con gifs, videos en mp4 o imagenes en png o jpg. Espero que este tutorial les haya ayudado a entender cómo funciona el Notification Service Extension y cómo implementarlo en sus aplicaciones. Un saludo y no lo olviden: no matter what, always keep-coding.

Por: Uriel Layuno Alfaya

Desarrollador de iOS en O2O – MO2O I Digital Business, Mobile One2One

Si tienes algo que deseas compartir o quieres formar parte de KeepCoding, escríbenos a [email protected]

Fernando Rodríguez

iOS Developer & Co-Fundador de KeepCoding

Posts más leídos