Tu primera aplicación de WatchKit interacción con el usuario

En el tutorial anterior, exploramos los fundamentos del desarrollo de WatchKit. Creamos un proyecto en Xcode, agregamos 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 que vivas en el desierto, eso no es muy útil para una aplicación de clima. En este tutorial, vamos a llenar la interfaz de usuario con datos y crear algunas acciones..

1. Actualizando la interfaz de usuario

Paso 1: Reemplazo WKInterfaceDate

Antes de poblar la interfaz de usuario con datos, necesitamos hacer un pequeño cambio. En el tutorial anterior, agregamos un WKInterfaceDate instancia en el grupo inferior para mostrar la hora y fecha actuales. Sin embargo, sería más útil mostrar la hora y la fecha de los datos que estamos mostrando. El motivo de este cambio se aclarará en unos instantes..

Abierto Interface.storyboard, eliminar el WKInterfaceDate instancia en el grupo inferior y reemplazarlo con una WKInterfaceLabel ejemplo. Establecer la etiqueta Anchura atribuir a Relativo al contenedor y la etiqueta Alineación a la derecha alineado.

Paso 2: Agregando Outlets

Para actualizar la interfaz de usuario con datos dinámicos, necesitamos crear algunos puntos de venta en el Controlador de interfaz clase. Abre el guión gráfico en el editor principal y InterfaceController.swift en el Editor asistente a la derecha. Seleccione la etiqueta superior en el primer grupo y Control-Arrastrar de la etiqueta a la Controlador de interfaz clase para crear una salida. Nombra la salida locationLabel.

Repita estos pasos para las otras etiquetas, nombrándolos etiqueta de temperatura y fechaLabel respectivamente. Esto es lo que el Controlador de interfaz la clase debe verse como cuando hayas terminado.

importar WatchKit importar Foundation class InterfaceController: WKInterfaceController @IBOutlet weak var dateLabel: WKInterfaceLabel! @IBOutlet weak var locationLabel: WKInterfaceLabel! @IBOutlet débil var temperatureLabel: WKInterfaceLabel! override func awakeWithContext (context: AnyObject?) super.awakeWithContext (context) override func willActivate () // Este método se llama cuando el controlador de vista de vigilancia está a punto de ser visible para el usuario super.willActivate ()) override func didDeactivate ( ) // Este método se llama cuando el controlador de vista de reloj ya no es visible super.didDeactivate ()

Ahora puede ser un buen momento para echar un vistazo más de cerca a la implementación del Controlador de interfaz clase. En el tutorial anterior, mencioné que Controlador de interfaz hereda de WKInterfaceController. A primera vista, puede parecer como si un WKInterfaceController instancia se comporta como una UIViewController ejemplo, pero también aprendimos en el tutorial anterior que hay una serie de diferencias clave.

Para ayudarnos, Xcode ha poblado la Controlador de interfaz Clase con tres métodos anulados. Es importante comprender cuándo se invoca cada método y para qué puede o debe usarse..

awakeWithContect (_ :)

En el awakeWithContext (_ :) Método, usted configura e inicializa el controlador de interfaz. Quizás se pregunte en qué se diferencia de la en eso método. los awakeWithContext (_ :) El método se invoca después de que se inicializa el controlador de interfaz. El método acepta un parámetro, un objeto de contexto que permite a los controladores de interfaz pasar información entre sí. Este es el enfoque recomendado para pasar información a través de escenas, es decir, controladores de interfaz.

se activará

los se activará El método es similar al viewWillAppear (_ :) método de la UIViewController clase. los se activará El método se invoca antes de que la interfaz de usuario del controlador de interfaz se presente al usuario. Es ideal para ajustar la interfaz de usuario antes de que se presente al usuario..

didDeactivate

los didDeactivate método es la contraparte de la se activará Método y se invoca cuando se ha eliminado la escena del controlador de interfaz. Cualquier código de limpieza entra en este método. Este método es similar al viewDidDisappear (_ :) método encontrado en el UIViewController clase.

Con lo anterior en mente, podemos comenzar a cargar datos y actualizar la interfaz de usuario de nuestra aplicación WatchKit. Empecemos con la carga de datos meteorológicos..

2. Cargando datos del clima

Mejores prácticas

Podría estar pensando que el siguiente paso implica una llamada de la API a un servicio meteorológico, pero ese no es el caso. Si estuviéramos construyendo una aplicación iOS, tendrías razón. Sin embargo, estamos creando una aplicación WatchKit..

No se recomienda realizar llamadas complejas a la API para obtener datos para completar la interfaz de usuario de una aplicación WatchKit. A pesar de que Apple no menciona explícitamente esto en la documentación, un ingeniero de Apple mencionó estas mejores prácticas no escritas en los foros de desarrolladores de Apple..

La aplicación WatchKit es parte de una aplicación iOS y es la aplicación iOS que se encarga de obtener datos de un servidor remoto. Hay varios enfoques que podemos tomar para hacer esto, la búsqueda de antecedentes es una buena opción. En este tutorial, sin embargo, no vamos a enfocarnos en ese aspecto.

En su lugar, agregaremos datos ficticios al paquete de la extensión WatchKit y los cargaremos en el awakeWithContext (_ :) método que discutimos anteriormente.

Crea un archivo en blanco seleccionando Nuevo> Archivo ...  desde el Expediente menú. Escoger Vacío desde el iOS> Otros seccionar y nombrar el archivo weather.json. Vuelve a comprobar que estás agregando el archivo a la Extensión RainDrop WatchKit. No pase por alto este pequeño pero importante detalle. Rellene el archivo con los siguientes datos.

"ubicaciones": ["ubicación": "Cupertino", "temperatura": 24, "marca de hora": 1427429751, "ubicación": "Londres", "temperatura": 11, "marca de hora": 1427429751, "location": "París", "temperature": 9, "timestamp": 1427429751, "location": "Bruselas", "temperature": 11, "timestamp": 1427429751]

Compartir datos

Compartir datos entre la aplicación iOS y la aplicación WatchKit es un tema importante. Sin embargo, este tutorial se enfoca en poner en funcionamiento su primera aplicación WatchKit. En un futuro tutorial, me centraré en compartir datos entre un iOS y una aplicación WatchKit.

Aunque no cubriremos el intercambio de datos en este tutorial, es importante saber que la aplicación iOS y la extensión WatchKit no comparten un entorno limitado. Ambos objetivos tienen su propia zona de pruebas y eso es lo que hace que compartir datos sea menos trivial de lo que parece.

Para compartir datos entre el iOS y la aplicación WatchKit, necesita aprovechar los grupos de aplicaciones. Pero ese es un tema para un futuro tutorial..

Paso 1: Añadiendo SwiftyJSON

Swift es un gran lenguaje, pero algunas tareas son más simples en Objective-C que en Swift. El manejo de JSON, por ejemplo, es una de esas tareas. Para facilitar esta tarea, he optado por aprovechar la popular biblioteca SwiftyJSON.

Descargue el repositorio de GitHub, descomprima el archivo y agregue SwiftyJSON.swift al Extensión RainDrop WatchKit grupo. Este archivo se encuentra en el Fuente Carpeta del archivo. Vuelva a comprobar que SwiftyJSON.swift se agrega el Extensión RainDrop WatchKit objetivo.

Paso 2: Implementando Datos del tiempo

Para facilitar el trabajo con los datos meteorológicos almacenados en weather.json, Vamos a crear una estructura llamada Datos del tiempo. Seleccionar Nuevo> Archivo ... desde la Expediente menú, elegir Archivo rápido desde el iOS> Fuente sección, y nombre el archivo Datos del tiempo. Asegúrese de que el archivo se agrega a la Extensión RainDrop WatchKit objetivo.

La implementación de la Datos del tiempo La estructura es corta y simple. La estructura define tres propiedades constantes., fecha, ubicación, y temperatura.

importar Foundation struct WeatherData let date: NSDate let location: String let temperature: Double

Debido a que el valor de la temperatura de weather.json Está en Celcius, también implementamos una propiedad computada. fahrenheit para facilitar la conversión entre Celcius y Fahrenheit.

var fahrentheit: Doble temperatura de retorno * (9/5) + 32

También definimos dos métodos de ayuda. toCelciusString y toFahrenheitString Para facilitar el formateo de los valores de temperatura. ¿No amas la interpolación de cuerdas de Swift??

func toCelciusString () -> String return "\ (temperatura) ° C" func toFahrenheitString () -> String return "\ (fahrentheit) ° F"

Como dije, la implementación de la Datos del tiempo La estructura es corta y simple. Así debería ser la implementación.

importar Foundation struct WeatherData let date: NSDate let location: String let temperature: Double var fahrentheit: Double temperatura de retorno * (9/5) + 32 func toCelciusString () -> String return "\ (temperature) ° C"  func toFahrenheitString () -> String return "\ (fahrentheit) ° F"

Paso 3: Cargando datos

Antes de cargar los datos desde weather.json, Necesitamos declarar una propiedad para almacenar los datos del clima. La propiedad, datos del tiempo, es de tipo [Datos del tiempo] y contendrá los contenidos de weather.json como instancias de la Datos del tiempo estructura.

var weatherData: [WeatherData] = []

Para facilitar su uso, también declaramos una propiedad computada., clima, que nos da acceso al primer ítem de la datos del tiempo formación. Son los datos de este. Datos del tiempo instancia que vamos a mostrar en el controlador de interfaz. ¿Puedes adivinar por qué necesitamos declarar la clima propiedad como opcional?

var weather: WeatherData? return weatherData.first

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

override func awakeWithContext (context: AnyObject?) super.awakeWithContext (context) // Cargar datos meteorológicos loadWeatherData ()

La implementación de loadWeatherData Es probablemente el fragmento de código más desalentador que veremos en este tutorial. Como dije, el análisis de JSON no es trivial en Swift. Afortunadamente, SwiftyJSON hace la mayor parte del trabajo pesado para nosotros.

func loadWeatherData () let path = NSBundle.mainBundle (). pathForResource ("weather", ofType: "json") si let path = path let data = NSData (contentsOfFile: path) si let data = data let weatherData = JSON (datos: datos) permite a ubicaciones = tiempoDatos ["ubicaciones"]. Array si deja ubicaciones = ubicaciones para ubicación en ubicaciones deja marca de tiempo = ubicación ["marca de tiempo"]. ¡Doble! let date = NSDate (timeIntervalSinceReferenceDate: timestamp) let model = WeatherData (fecha: fecha, ubicación: ubicación ["ubicación"]. cadena, temperatura: ubicación ["temperatura"]. ¡doble!) self.weatherData.append (modelo) 

Obtenemos el camino a weather.json y cargar su contenido como NSData objeto. Utilizamos SwiftyJSON para analizar el JSON, pasando el NSData objeto. Obtenemos una referencia a la matriz para la clave. localizaciones y bucle sobre cada ubicación.

Normalizamos los datos meteorológicos convirtiendo la marca de tiempo en una NSDate instancia e inicializar un Datos del tiempo objeto. Finalmente, agregamos el Datos del tiempo objetar al datos del tiempo formación.

Espero que estén de acuerdo en que la implementación no es tan difícil. Debido a que Swift nos obliga a realizar una serie de comprobaciones, la implementación parece más compleja de lo que realmente es.

3. Poblando la interfaz de usuario

Con los datos meteorológicos listos para usar, es hora de actualizar la interfaz de usuario. Como expliqué anteriormente, la actualización de la interfaz de usuario debe realizarse en el se activará método. Echemos un vistazo a la implementación de este método..

anular func willActivate () // Este método se invoca cuando el controlador de vista de visualización está a punto de ser visible para el usuario super.willActivate () si let weather = self.weather locationLabel.setText (weather.location) // Etiqueta de temperatura de actualización self .updateTemperatureLabel () // Actualizar etiqueta de fecha self.updateDateLabel ()

Después de invocar el se activará Método de la superclase, desenvolvemos el valor almacenado en el clima propiedad. Para actualizar la etiqueta de ubicación, invocamos. setText, pasando en el valor almacenado en el ubicación propiedad de la clima objeto. Para actualizar las etiquetas de temperatura y fecha, invocamos dos métodos de ayuda. Prefiero guardar el se activará Método breve y conciso y, lo que es más importante, no me gusta repetirlo..

Antes de ver estos métodos de ayuda, necesitamos saber si la temperatura debe mostrarse en Celcius o Fahrenheit. Para resolver este problema, declare una propiedad., celcio, de tipo Bool y establecer su valor inicial a cierto.

var celcius: Bool = true

La implementación de updateTemperatureLabel es facil de entender Desenvolvemos con seguridad el valor almacenado en clima y actualizar la etiqueta de temperatura en función del valor de celcio. Como puede ver, los dos métodos de ayuda de la Datos del tiempo La estructura que creamos anteriormente es útil.

func updateTemperatureLabel () si let weather = self.weather if self.celcius temperatureLabel.setText (weather.toCelciusString ()) else temperatureLabel.setText (weather.toFahrenheitString ())

La implementación de updateDateLabel no es dificil tampoco Inicializamos un NSDateFormatter instancia, establecer su formato de fecha propiedad, y convertir la fecha de la clima objetar llamando stringFromDate (_ :) sobre el dateFormatter objeto. Este valor se utiliza para actualizar la etiqueta de fecha..

func updateDateLabel () var date: NSDate = NSDate () // Initialize Date Formatter let dateFormattter = NSDateFormatter () // Configurar Date Formatter dateFormattter.dateFormat = "d / MM HH: mm" si let weather = self.weather date = weather.date // Actualizar la etiqueta de fecha dateLabel.setText (dateFormattter.stringFromDate (date))

Construye y ejecuta la aplicación para ver el resultado. La interfaz de usuario ahora debe estar poblada con los datos de weather.json.

4. Cambiando a Fahrenheit

Esto luce bien. ¿Pero no sería genial si añadiéramos soporte para Celcius y Fahrenheit? Esto es fácil de hacer ya que ya hemos sentado la mayoría de las bases.

Si la fuerza de usuario toca la interfaz de usuario de un controlador de interfaz de usuario, se muestra un menú. Por supuesto, esto solo funciona si hay un menú disponible. Veamos como funciona esto..

Abierto Interface.storyboard y añadir un menú a la Controlador de interfaz en el Esquema del documento a la izquierda. Por defecto, un menú tiene un elemento de menú. Necesitamos dos elementos de menú, así que agregue otro elemento de menú al menú.

Tenga en cuenta que el menú y sus elementos de menú no están visibles en la interfaz de usuario. Esto no es un problema ya que no podemos configurar el diseño del menú. Lo que podemos cambiar es el texto de un elemento del menú y su imagen. Comprenderás mejor lo que eso significa cuando presentamos el menú..

Seleccione el elemento del menú superior, abra el Inspector de atributos, conjunto TítuloCelcio, y ImagenAceptar. Seleccione el elemento inferior del menú y establezca TítuloFahrenheit y ImagenAceptar.

A continuación, abrir InterfaceController.swift en el Editor asistente a la derecha. Control-Arrastrar desde el elemento del menú superior a InterfaceController.swift y crea una acción llamada aCelcio. Repita este paso para el elemento inferior del menú, creando una acción llamada a Fahrenheit.

La implementación de estas acciones es corta. En aCelcio, comprobamos si el celcio la propiedad se establece en falso, Y, si es así, establecemos la propiedad en cierto. En a Fahrenheit, comprobamos si el celcio la propiedad se establece en cierto, Y, si es así, establecemos la propiedad en falso.

@IBAction func toCelcius () if! Self.celcius self.celcius = true @IBAction func toFahrenheit () if self.celcius self.celcius = false

Si el valor de celcio Cambios, necesitamos actualizar la interfaz de usuario. ¿Qué mejor manera de lograr esto implementando un observador de propiedades en el celcio propiedad. Solo necesitamos implementar un se estableció observador de propiedad.

var celcius: Bool = true didSet if celcius! = oldValue updateTemperatureLabel ()

El único detalle que vale la pena mencionar es que la interfaz de usuario solo se actualiza si el valor de celcio cambió Actualizar la interfaz de usuario es tan simple como llamar updateTemperatureLabel. Cree y ejecute la aplicación WatchKit en el simulador de iOS para probar el menú.

Vale la pena mencionar que el simulador de iOS imita la capacidad de respuesta de un dispositivo físico. Qué significa eso? Recuerde 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 toca un elemento del menú, el evento táctil se envía a través de una conexión Bluetooth al iPhone. La extensión WatchKit procesa el evento y envía las actualizaciones a Apple Watch. Esta comunicación es bastante rápida, pero no es tan rápida como si la extensión y la aplicación se ejecutaran en el mismo dispositivo. El simulador de iOS imita ese pequeño retraso para ayudar a los desarrolladores a tener una idea del rendimiento.

Conclusión

Una vez que haya girado la cabeza alrededor de la arquitectura de una aplicación WatchKit, será mucho más fácil comprender las posibilidades y limitaciones de la primera generación de aplicaciones WatchKit. En este tutorial, solo hemos cubierto lo esencial del desarrollo de WatchKit. Hay mucho más por descubrir y explorar. Manténganse al tanto.