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:{ "aps":{ "alert":"Testing.. (0)", "badge":1, "sound":"default" } }
{"aps":{ "alert": { "title":"Testing...(0)", "body":"Mensaje de prueba" }, "badge":1, "sound":"default", "mutable-content":1 } }
{ "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:
- Comprobar si se ha dado un error. En caso afirmativo imprimir el mismo devolver una excepción o lo que queramos.
- 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 .
- 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í:
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]