Home » Análisis » Análisis: notificaciones en iOS 10, tvOS 10 y watchOS 3
Banner Notifications

Análisis: notificaciones en iOS 10, tvOS 10 y watchOS 3

Las notificaciones son un elemento imprescindible para el uso de nuestros dispositivos móviles o tabletas y en iOS 10, watchOS 3 o tvOS 10 hay importantes novedades que afectan tanto al usuario como a los desarrolladores. En esencia, existen dos tipos de notificaciones: las remotas y las locales. Las primeras son aquellas que se envían desde un aplicación de servidor al servicio APN de Apple para que lleguen al dispositivo del usuario afectado por la misma. Las segundas, son las que las propias apps generan dentro del propio dispositivo. Ahora con iOS 10, se suma un nuevo tipo: el de las notificaciones que genera la propia app dentro de sí misma cuando está abierta.

La mecánica de las notificaciones

El framework de notificaciones de usuario se compone de varios elementos o pasos para gestionar estas: registro, contenido, programación, gestión y acciones. A esto, en iOS 10 se le suma también las extensiones de notificaciones, un tipo nuevo de extensión (con plantilla incluida en Xcode 8) que nos permiten ir más allá en cuanto a contenido enriquecido o gestión dentro de las notificaciones en la nuevas versiones de los sistemas.

Las notificaciones tienen, además, varias formas de hacerse notar por el usuario: como alertas visuales, a través de sonido o vibración y añadiendo un número al icono de la app (lo que es el badging).

Normalmente, cuando lanzamos una notificación (bien remota o bien local) una vez la hemos lanzado o programado, nos olvidamos de ella. Ya no podemos hacer nada más. Pero ahora la cosa cambia porque podemos dar un identificador de contenido a la misma, con un nuevo parámetro, de forma que si mandamos un nueva notificación con el mismo ID de una notificación anterior, lo que el sistema hará es borrar la antigua y sustituirla por una nueva. Incluso si la notificación antigua estaba por debajo en la cola de llegada, ahora pasará a estar arriba y con la fecha de actualización de la misma.

También tenemos la opción de borrar una notificación simplemente, de forma que el usuario dejará de verla en el centro de notificaciones (en caso de haberla visto ya) o ni siquiera le aparecerá si aun no la ha visto en, por ejemplo, la pantalla de bloqueo (o tal vez porque está programada pero no se ha lanzado). Y todo, simplemente, a partir de un identificador que se repite para que el sistema sepa que nos referimos a una notificación ya enviada. Nada más.

Notificaciones locales y remotas

Las notificaciones locales se lanzan en las apps cuando tenemos una tarea asíncrona determinada por la que queremos informar al usuario, aunque nuestra app ya esté cerrada. Normalmente se programan cuando el usuario decide quitar la app y pueden servir para recordar alguna tarea, alertas de calendario o incluso en disparadores de localización (al llegar a un lugar salta la alerta). También podemos crearlas basadas en un tiempo de expiración, por ejemplo, si tenemos que esperar unos minutos u horas a que alguna acción se complete en un juego (se construya una casa) y que cuando expire el tiempo se nos avise que nuestra casa ya está construida.

En el caso de las remotas, el origen siempre parte de un sistema remoto: una aplicación server-side que genera notificaciones de eventos ajenos al terminal, como una aplicación de mensajería, alertas de noticias o de eventos deportivos. Estas siempre se sirven a través del servicio APNs (Apple Push Notification Service) y también pueden usar las nuevas funciones de actualización y borrado.

Cambios en la API

Hasta ahora, los callbacks que gestionaban las notificaciones remotas y locales eran diferentes y se nos obligaba a gestionar el código de forma diferente. Además, el control sobre las notificaciones una vez programadas era muy limitado. En la nueva versión la API tiene paridad en las funciones entre notificaciones remotas o locales, se puede poner más contenido, la ruta de código para manejar las notificaciones (el handling) es la misma en remotas y locales, se han simplificado las delegaciones, mejorado la gestión general e incluido una opción para notificaciones dentro de la propia app. Y lo más importante: las extensiones. Existen extensiones para las propias notificaciones y además, se pueden programar o manejar notificaciones desde las propias extensiones de una app.

De igual forma, la nueva API es unificada y permite la gestión de todas ellas tanto en watchOS como iOS y tvOS. Mientras en iOS tiene soporte completo de control de notificaciones en watchOS tienes un soporte extendido de las notificaciones redirigidas desde el teléfono, así como la posibilidad (y esto es lo más interesante) de lanzar notificaciones locales desde las propias watchApps. En tvOS las notificaciones se limitan a los contadores en los iconos de la app, donde pueden indicarse cosas como la publicación de un nuevo episodio de una serie que sigues o un turno entrante en un juego por turnos (por citar algunos ejemplos).

Ciclo completo

El ciclo comienza por el registro, el momento en que solicitamos al usuario el envío de notificaciones de nuestra app por primera vez. Y para ello, nada más simple que una simple línea en Swift 3 que lanza un array con las diferentes posibilidades de notificación que queremos autorizar, como enumeraciones.

De esta forma, solicitamos autorización de notificaciones que sean de tipo alerta, con sonido y con acumulación de número de notificación en el propio icono (badge). Nada más. Una nueva opción interesante que tenemos, es la posibilidad de solicitar al sistema si nuestra app tiene ya pre-autorizadas las notificaciones y cuáles de ellas.

Aquí lo importante es el parámetro settings del closure, un array con los valores enumerados como los vistos al pedir el registro. En el caso de notificaciones remotas, necesitamos una solicitud de registro que es más simple aun.

De esta forma obtenemos el token de identificación del dispositivo que luego hemos de usar desde nuestra app server-side para al enviar la notificación al servicio APNs, incluir dicho token como destino de la notificación.

Cuando queremos configurar la notificación, hemos de tener en cuenta que tenemos más propiedades que antes porque podemos dar un título y un subtítulo, además del contenido de la misma. Por lo tanto, la información ahora será mucho más completa.

En este caso, creamos un objeto UNMutableNotificationContent porque queremos tener la opción de una posible actualización o borrado de la misma en el futuro, tras la programación de la misma e incluso tras el envío y recepción. En el caso de la notificación remota, el recibo a enviar (el payload) también sería de un estilo similar, teniendo en cuenta los nuevos parámetros.

Otra de las novedades es la posibilidad de incluir en los contenidos adjuntos multimedia. De esta forma, podemos enviar una foto u otro tipo de adjunto de medios que le den un mayor valor a la notificación, y este se podrá ver desde la propia notificación sin necesidad de entrar en la app que lo generó. Solo hay que añadir un parámetro attachments al objeto UNMutableNotificationContent, que para este caso es un array de objetos UNNotificationAttachment. Los adjuntos se recuperan de un URL que contenga una imagen, un sonido o incluso un vídeo. No tenemos que gestionarlo, solo pasarle la URL.

Un objeto UNNotificationAttachment devuelve un throws por lo que necesita ser gestionado mediante control de errores. Para el ejemplo, hemos preferido ir por la vía rápida y usar try! para que dicho control actúe como un opcional desempaquetado implícitamente, pero no es recomendable hacer esto si no tenemos la total seguridad que el fichero foto.jpg al que intentamos acceder no existe en el Bundle principal del sistema.

También tenemos la opción de configurar disparadores (triggers) que **permitan configurar momentos donde las notificaciones se lancen. Por ejemplo, a partir de un objeto UNTimeIntervalNotificationTrigger podemos definir un intervalo e incluso si este queremos que se repita o no.

En el caso que busquemos una notificación que se lance en un momento determinado, también podemos programarla con una fecha concreta usando un objeto UNCalendarNotificationTrigger al que podemos pasar un objeto DateComponents que tenga un momento temporal que permita lanzar un notificación en un día y hora concreto de la semana, todas las semanas. Y si queremos, podemos lanzar notificaciones cuando nuestro dispositivo se aproxime a una ubicación contenido en un objeto CLRegion usando UNLocationNotificationTrigger.

Notificaciones Entrega

En el caso que la notificación sea remota, tras el registro (obvio) enviamos el contenido y cuando se lanza el trigger se realiza la programación del evento. En el caso local, se añade la petición que se registra al UNuserNotificationCenter y luego se lanza el trigger que controla los eventos o se valida.

Si queremos ver el ejemplo completo sería así:

Si queremos actualizar esta notificación aunque ya se haya enviado o entregado, solo tenemos que tener en cuenta el parámetro identifier del objeto UNNotificationRequest. Si es el mismo que se usó con la anterior notificación, el sistema borrará la que se entregó con ese identificador y pondrá esta nueva en su lugar (colocándola al principio de la cola pues se registrará como entregada en el momento de la actualización).

Si solo queremos actualizar el tiempo del trigger, volveríamos a pasar todos los datos de identifier y content tal cual, pero con un nuevo objeto UNTimeIntervalNotificationTrigger que sustituiría al anterior, lo que nos permite igualmente actualizar el disparador de una notificación no entregada aun.

En caso que busquemos solo borrarla, solo hay que llamar al método removePendingNotificationRequest del singleton de UNUserNotificationCenter y pasarle este identificador.

El parámetro withIdentifiers es un array, lo que indica claramente que en una misma llamada podemos borrar varias notificaciones a la vez.

Acciones

Acciones

Al igual que podíamos hacer en versiones anteriores, podemos fijar posibles acciones a realizar por la notificación. De hecho, incluso podemos crear acciones para cuando se descarte la notificación (una nueva opción de iOS 10) y limpiemos esta, no solo de nuestro dispositivo, si no de todos los que hayan recibido esta también.

Estas acciones pueden usarse tanto en iOS como, ahora, también en watchOS, y la forma de invocarlas es la misma. Independiente del contexto donde se muestren, nosotros recibiremos en nuestro programa el mismo comportamiento, tanto a la hora de crear, invocar, programar, gestionar o recibir el resultado de una interacción con la misma.

Como podemos ver, primero definimos el objeto de la acción con UNNotificationAction y este (o todos los que creemos) los pasamos en un array al parámetro actions al crear las categorías con UNNotificationCategory. Y además, podemos definir dos niveles de acciones: el de acciones mínimas y el total de ellas. Luego, lo pasamos al singleton estableciendo la categorías (o varias de ellas) con setNotificationCategories y nada más.

Para gestionar posteriormente las notificaciones, cuando se lance la acción, lo hacemos mediante la delegación correspondiente con el protocolo UNUserNotificationCenterDelegate que recibe la función userNotificationCenter donde lo que nos importa es el contenido del parámetro response.

Notificaciones Acciones

Aquí lo importante es el objeto UNNotificationResponse que incluye la cadena del identificador de la acción que se ha pulsado, con un posible texto de usuario en un parámetro userText (en caso que sea, por ejemplo, contestar algo) y luego además lleva la notificación en sí, donde a través de sus métodos podremos acceder a su identificador, contenido y disparador (trigger).

Conclusiones

Como podemos ver, las posibilidades son muy interesantes, y esto es solo el punto de vista básico. Si a esto le unimos el uso de extensiones, las posibilidades de las notificaciones se multiplican porque al añadirle una extensión podríamos incluir vídeo en streaming en directo de alguna fuente, información en tiempo real de un mapa o cualquier otro contenido que se nos ocurra y que pueda ir en una extensión con contenido vivo y enriquecido. Y todo esto incluyendo la funcionalidad que tenga la propia extensión incluida en la notificación.

Es importante notar que, aunque en la primera beta, la interacción con las notificaciones y el acceso al contenido enriquecido está limitado a los dispositivos 3D Touch, Apple ya ha confirmado que cualquier dispositivo de los que soportan iOS 10 tendrá una forma sencilla de acceder a esas opciones contextuales y enriquecidas sin necesidad de disponer el 3D Touch (aunque obviamente no será tan cómodo ni intuitivo).

Sin duda, las nuevas notificaciones son muy interesantes y la forma en que funcionan han mejorado muchos puntos, así que os invitamos a experimentar con ellas y que nos contéis qué tal os ha ido con las pruebas. Recordad: siempre probad y experimentad. Y Good Apple Coding.

Acerca de Julio César Fernández

Analista, consultor y periodista tecnológico, desarrollador, empresario, productor audiovisual, actor de doblaje e ingeniero de vídeo y audio.

Otras recomendaciones

Diseñando para el iPhone X

iPhone X (léase 10). El nuevo y más deseado dispositivo de Apple, no carente de …

  • Alberto Jiménez

    No tengo manera humana de hacer cargar una imagen desde una URL remota en la notificación.estoy usando firebasse para las notificaciones y cuando añado dentro del applicationreceivedRemoteMessage el content.attachments y le pongo al UNNotificationAttachment la dirección url la toma como invalida. Imagino que ahí lo que pide es una dirección internat temporal. Es decir, tengo que descargar la imagen antes y luego cargarla. Y no tengo ni idea jajajaja