Unlimited Plugins, WordPress themes, videos & courses! Unlimited asset downloads! From $16.50/m
Advertisement
  1. Code
  2. WatchKit

Tu Primera Aplicación WatchKit: Interacción del Usuario

by
Difficulty:IntermediateLength:LongLanguages:

Spanish (Español) translation by Javier Salesi (you can also view the original English article)

En el tutorial anterior, exploramos los fundamentos del desarrollo en Watchkit. Creamos un proyecto en Xcode, añadimos una aplicación Watchkit, y creamos una interfaz de usuario básica.

La interfaz de usuario de nuestra aplicación WatchKit actualmente muestra datos estáticos. A menos de que vivas en el desierto, eso no es muy útil para una aplicación del clima. En éste tutorial, vamos a llenar la interfaz de usuario con datos y crear unas cuantas acciones.

1. Actualizando la Interfaz de Usuario

Paso 1: Remplazar WKInterfaceDate

Antes de que llenemos la interfaz de usuario con datos, necesitamos hacer un pequeño cambio. En el tutorial anterior, añadimos una instancia WKInterfaceDate al grupo del sector inferior para mostrar la fecha y hora actual. Sería más útil, sin embargo, mostrar la hora y la fecha de los datos que estamos mostrando. La razón para éste cambio será aclarada en unos momentos.

Abrimos Interface.storyboard, removemos la instancia WKInterfaceDate en el grupo de abajo y la remplazamos con una instancia WKInterfaceLabel. Establece el atributo Width (Anchura) de label (etiqueta) en Relative to Container (Relativo a Contenedor) y el atributo Alignment (Alineación) de label a derecha.

Adding a Label

Paso 2: Añadimos Outlets

Para actualizar la interfaz de usuario con datos dinámicos, necesitamos crear unos outlets en la clase InterfaceController. Abrimos el storyboard en el editor principal y InterfaceController.swift en el Assistant Editor (Editor Asistente) de la derecha. Seleccionamos el label superior en el primer grupo y Control-Drag del label a la clase InterfaceController para crear un outlet. Nombramos el outlet locationLabel.

Repetimos éstos pasos para los otros labels, nombrándolos temperatureLabel y dateLabel respectivamente. Así es como debería verse la clase InterfaceController cuando hayamos terminado.

Ahora puede ser un buen momento para poner más atención a la implementación de la clase InterfaceController. En el anterior tutorial, mencioné que InterfaceController hereda de WKInterfaceController. A primera vista, puede parecer como si una instancia WKInterfaceController se comportara como una instancia UIViewController, pero también aprendimos en el tutorial previo que hay varias diferencias clave.

Para ayudarnos, Xcode ha llenado la clase InterfaceController con tres métodos aplicando el modificador override. Es importante entender cuando cada es invocado cada método y para lo que puede o debe ser usado.

awakeWithContect(_:)

En el método awakeWithContext(_:), estableces e inicializas el controlador de interfaz. Puedes estarte preguntando como difiere del método init. El método awakeWithContext(_:) es invocado después de que es inicializado el controlador de interfaz. El método acepta un parámetro, un objeto de contexto que permite a controladores de interfaz pasar información uno a otro. Éste es el planteamiento recomendado para pasar información a través de escenas, o sea, controladores de interfaz.

willActivate

El método willActivate es similar al método viewWillAppear(_:) de la clase UIViewController. El método willActivate es invocado antes de que la interfaz de usuario del controlador de interfaz sea presentada al usuario. Es ideal para modificar la interfaz de usuario antes de que sea presentada al usuario.

didDeactivate

El método didDeactivate es la contraparte del método willActivate y es invocado cuando la escena del controlador de interfaz ha sido removida. Cualquier código de limpieza va en éste método. Éste método es similar al método viewDidDisappear(_:) encontrado en la clase UIViewController.

Teniendo en mente lo mencionado anteriormente, podemos comenzar a cargar datos y actualizar la interfaz de usuario de nuestra aplicación WatchKit. Comencemos con la carga de datos del clima.

2. Cargando los Datos del Clima

Mejores Prácticas

Podrías estar pensando que el próximo paso involucra una llamada API a un servicio de meteorología, pero éste no es el caso. Si estuviéramos creando una aplicación iOS, tendrías razón. Sin embargo, estamos creando una aplicación WatchKit.

No se recomienda hacer complejas llamadas API para tomar datos que llenarán la interfaz de usuario de una aplicación WatchKit. Aunque Apple no menciona explícitamente ésto en la documentación, un ingeniero de Apple si mencionó esta práctica no escrita en los foros del desarrollador de Apple.

La aplicación WatchKit es parte de una aplicación iOS y es la aplicación iOS que se encarga de traer datos de un backend remoto. Hay varios planteamientos que podemos tomar para hacer ésto, siendo una buena elección las descargas en segundo plano. En éste tutorial, sin embargo, no vamos a enfocarnos en ese aspecto.

En cambio, añadiremos datos de ejemplo al paquete de la extensión WatchKit y los cargaremos en el método awakeWithContext(_:) que discutimos previamente.

Creamos un archivo vacío al seleccionar New>File... del menú File. Elige Empty de la sección iOS>Other y nombra el archivo weather.json. Checa bien que estés añadiendo el archivo a la extensión RainDrop Watchkit Extension. No omitas éste pequeño pero importante detalle. Llena el archivo con los siguientes datos.

Compartiendo Datos

Compartir datos entre la aplicación iOS y la aplicación WatchKit es un tópico importante. Sin embargo, éste tutorial se enfoca en tener tu aplicación WatchKit funcionando adecuadamente. En un próximo tutorial, me enfocaré en compartir datos entre una aplicación iOS y una WatchKit.

Aunque no cubriremos la compartición de datos en éste tutorial, es importante saber que la aplicación iOS y la extensión WatchKit no comparten una caja de arena. Ambos targets tienen su propia caja de arena y eso es lo que hace la compartición de datos menos trivial de lo que parece.

Para compartir datos entre aplicaciones iOS y WatchKit necesitas apalancar grupos de aplicaciones. Pero ese es un tópico para un tutorial futuro.

Paso 1: Añadir SwiftyJSON

Swift es un gran lenguaje, pero algunas tareas son más simples en Objetive-C que en Swift. Manejar JSON, por ejemplo, es una de ellas. Para hacer ésta tarea más fácil, he elegido incluir la popular librería SwiftyJSON.

Descarga el repositorio de GitHub, descomprime el archivo, y añade SwiftJSON.swift al grupo RainDrop WatchKit Extension. Éste fichero se localiza en el directorio Source del archivo. Revisa bien que SwiftyJSON.swift sea añadido al target RainDrop WatchKit Extension

Adding the SwiftyJSON Library

Paso 2: Implementar WeatherData

Para hacer más fácil el trabajar con los datos meteorológicos en weather.json, vamos a crear una estructura llamada WeatherData. Selecciona New>File... del menú File, elige Swift File de la sección iOS>Source, y nombra el archivo WeatherData. Asegúrate de que el archivo se añada al target RainDrop WatchKit Extension.

La implementación de la estructura WeatherData es corta y simple. La estructura define tres propiedades constantes, date, location, y temperature.

Debido a que el valor de la temperatura de weather.json es en Celsius, también implementamos una propiedad calculada fahrenheit para una fácil conversión entre Celsius y Fahrenheit.

También definimos dos métodos auxiliares toCelciusString y toFahrenheidString para facilitar el formato de los valores de la temperatura. ¿No te gusta la interpolación de string de Swift?

Como mencioné, la implementación de la estructura WeatherData es corta y simple. Así es como se debe ver la implementación.

Paso 3: Cargar los Datos

Antes de que carguemos los datos desde weather.json, necesitamos declarar una propiedad para guardar los datos del clima. La propiedad, weatherData, es de tipo [WeatherData] y albergará el contenido de weather.json como instancias de la estructura WeatherData.

Para que sea fácil de usar, declaramos también una propiedad calculada, weather, que nos da acceso al primer elemento del arreglo weatherData. Son los datos de ésta instancia WeatherData los que mostraremos en el controlador de interfaz. ¿Puedes adivinar por qué necesitamos declarar la propiedad weather como opcional?

Cargamos los datos desde weather.json en el método awakeWithContext(_:) Para mantener limpia la implementación, invocamos un método auxiliar llamado loadWeatherData.

La implementación de loadWeatherData es probablemente el fragmento de código más intimidante que veremos en éste tutorial. Como señalé, parseando JSON no es trivial en Swift. Afortunadamente, SwiftyJSON hace la mayoría del trabajo pesado por nosotros.

Obtenemos la ruta hacia weather.json y cargamos su contenido como un objeto NSData. Usamos SwiftyJSON para parsear el JSON, pasando al objeto NSData. Obtenemos una referencia al arreglo para las locaciones clave e iteramos sobre cada locación.

Normalizamos los datos del clima al convertir la fecha a una instancia NSDate e inicializar un objeto WeatherData. Finalmente, añadimos el objeto WeatherData al arreglo weatherData.

Espero que estés de acuerdo de que la implementación no es tan difícil. Debido a que Swift nos obliga a hacer un número de revisiones, la implementación parece más compleja de lo que es en realidad.

3. Llenando la Interfaz de Usuario

Con los datos del clima listos para usarse, es momento de actualizar la interfaz de usuario. Como expliqué previamente, actualizar la interfaz de usuario necesita producirse en el método willActivate. Veamos la implementación de éste método.

Después de invocar el método willActivate de la superclase, tomamos el valor almacenado en la propiedad weather. Para actualizar el label locación, invocamos setText, pasamos el valor almacenado en la propiedad location del objeto weather. Para actualizar los label de temperatura y fecha, invocamos dos métodos auxiliares. Prefiero mantener el método willActivate breve y conciso, y, lo más importante, no me gusta repetir las cosas.

Antes de observar éstos métodos de ayuda, necesitamos saber si la temperatura necesitar ser mostrada en Celsius o en Fahrenheit. Para resolver éste problema, declaramos una propiedad, celcius, de tipo Bool y establecemos su valor inicial en true.

La implementación de updateTemperatureLabel es fácil de entender. Tomamos el valor guardado en weather y actualizamos el label temperatura basado en el valor de celcius. Como puedes ver, los dos métodos de ayuda de la estructura WeatherData que creamos previamente resultan útiles.

La implementación de updateDateLabel tampoco es difícil. Inicializamos una instancia NSDateFormatter, establecemos su propiedad dateFormat, y convertimos la fecha del objeto weather al llamar a stringFromDate(_:) en el objeto dateFormatter. Éste valor es utilizado para actualizar el label fecha.

Compilamos y ejecutamos la aplicación para ver el resultado. La interfaz de usuario debería ahora aparecer con los datos de weather.json.

The Finished User Interface of RainDrop

4. Cambiar a Fahrenheit

Ésto se ve bien. ¿Pero no debería ser fabuloso si añadimos soporte tanto para Celsius como para Fahrenheit? Ésto es fácil de hacer ya que hemos preparado el terreno anteriormente.

Si el usuario obliga a tocar la interfaz de usuario de un controlador de interfaz de usuario, se mostrará un menú. Claro, ésto sólo funciona si un menú está disponible. Veamos cómo funciona ésto.

Abrimos Interface.storyboard y añadimos un menú a Interface Controller en Document Outline a la izquierda. Por defecto, un menú tiene un elemento menú. Necesitamos dos elementos menú así que añadimos otro elemento menú al menú.

Adding a Menu with Two Menu Items

Nota que el menú y sus elementos menú no son visibles en la interfaz de usuario. Éste no es un problema ya que no podemos configurar el layout del menú. Lo que podemos configurar son el texto de un elemento menú y su imagen. Entenderás mejor lo que significa cuando presentemos el menú.

Seleccionamos el elemento superior del menú, abrimos el Attributes Inspector, establecemos Title en Celcius, e Image en Accept. Seleccionamos el elemento menú de abajo y establecemos Title en Fahrenheit y Image en Accept.

Configuring a Menu Item

Luego, abrimos InterfaceController.swift en el Assistant Editor a la derecha. Control-Drag del elemento menú superior a InterfaceController.swift y creamos una acción llamada toCelcius. Repetimos éste paso para el elemento menú inferior, creando una acción llamada toFahrenheit.

La implementación de éstas acciones es breve. En toCelcius, revisamos si la propiedad celcius está establecida en false, y, si es así, establecemos la propiedad a true. En toFahrenheit, checamos si la propiedad celcius está establecida en true, y, si es así, establecemos la propiedad en false.

Si el valor de celcius cambia, necesitamos actualizar la interfaz de usuario. Que mejor manera de lograr ésto al implementar una propiedad observador en la propiedad celcius. Sólamente necesitamos implementar un observador de propiedad didSet.

El único detalle que vale la pena mencionar es que la interfaz de usuario se actualiza sólamente si el valor de celcius cambió. Actualizar la interfaz de usuario es tan simple como llamar a updateTemperatureLabel. Compilamos y ejecutamos la aplicación WatchKit en el simulador iOS para probar el menú.

Cabe señalar que el simulador iOS imita la adaptabilidad de un dispositivo físico. ¿Qué significa eso? Recuerda que la extensión WatchKit se ejecuta en un iPhone mientras que la aplicación WatchKit se ejecuta en un Apple Watch. Cuando el usuario pulsa un elemento menú, el evento toque es enviado en una conexión Bluetooth al iPhone. La extensión WatchKit procesa el evento y envía cualquier actualización de regreso al Apple Watch. Ésta comunicación es muy rápida, pero no es tan rápida como si fueran a ejecutarse en el mismo dispositivo la extensión como la aplicación. Ésta corta demora es imitada por el Simulaor iOS para ayudar a los desarrolladores a tener una idea del desempeño.

Conclusión

Una vez que has entendido bien la arquitectura de una aplicación WatchKit, llega a ser mucho más fácil comprender las posibilidades y limitaciones de la primera generación de aplicaciones WatchKit. En éste tutorial, sólo hemos cubierto lo esencial del desarrollo en WatchKit. Hay mucho más por descubrir y explorar. Sigue en sintonía.

¡Sé el primero en conocer las nuevas traducciones–sigue @tutsplus_es en Twitter!

Advertisement
Advertisement
Advertisement
Advertisement
Looking for something to help kick start your next project?
Envato Market has a range of items for sale to help get you started.