Spanish (Español) translation by Javier Salesi (you can also view the original English article)
Introducción
En la WWDC 2015, Apple anunció su primera gran actualización del software Apple Watch, watchOS 2. Ésta nueva actualización trajo con ella muchas nuevas APIs y características que pueden ser aprovechadas por los desarrolladores, incluyendo aplicaciones nativas, más acceso al hardware de Apple Watch, y mejor comunicación con la aplicación padre iOS.
En éste tutorial, voy a mostrarte cómo aprovechar otra nueva característica, la capacidad de crear complicaciones personalizadas de reloj usando el framework ClockKit. Éste tutorial requiere que estés ejecutando Xcode 7 en OS X Yosemite (10.10) o superior.
Si todavía no lo sabes, las complicaciones del Apple Watch son los pequeños elementos de la interfaz que muestran información en la caráctula del reloj.



La captura de pantalla de arriba muestra como cinco complicaciones son desplegadas en la carátula Modular además del tiempo en la esquina superior derecha.
1. Crear el Proyecto
Crea un nuevo proyecto en Xcode, usando la plantilla watchOS > Application > iOS App with WatchKit App.



Posteriormente, configura el proyecto como se muestra abajo, asegurando que esté seleccionado Include Complication.



Una vez que Xcode ha creado tu proyecto, abre la ClockKit Introduction WatchKit Extension en el Project Navigator. Verás una nueva sección Complications Configuration como se muestra abajo.



Las cinco casillas de verificación Supported Families representan las diferentes familias de complicación que soporta tu aplicación. En éste tutorial, vamos a enfocarnos en la familia Modular Large. Puedes desmarcar las otras casillas de verificación por ahora.



Como se señaló en la Guía de Transición watchOS 2 de Apple, se recomienda ampliamente que tu aplicación soporte las cinco familias. La siguiente imagen muestra donde se utilizan éstas diferentes familias.



2. Crear la Complicación
Para enseñarte cómo usar ClockKit, vas a crear una complicación sencilla que muestra el tiempo, nombre, y género de programas de televisión ficticios en una estación particular durante todo el día.
Para comenzar, abre ComplicationController.swift en el directorio ClockKit Introduction WatchKit Extension. Xcode ha creado automáticamente éste archivo por tí. Contiene una clase ComplicationController
, que cumple con e implementa el protocolo CLKComplicationDataSource
.
Los métodos asociados con éste protocolo son cómo proporcionas datos a ClockKit sobre las complicaciones que quieres mostrar. Los métodos del protocolo contienen un manejador que debes llamar para pasar datos de vuelta a ClockKit.
Timelines (líneas de tiempo)
Cuando se proporcionan datos a ClockKit, lo haces en la forma de un timeline. Haces ésto al llenar el timeline de tu complicación con objetos de datos que son vinculados a un punto específico en el tiempo. Éstos objetos de datos son modelados por la clase CLKComplicationTimelineEntry
. Cuando un punto particular en el tiempo es alcanzado, ClockKit automáticamente muestra el contenido correcto para tu aplicación.
Tus entradas de timeline son recuperadas y almacenadas temporalmente por ClockKit mucho antes del tiempo en el que se mostrarán. Ésto significa que los datos deben poder recuperarse y agendarse por anticipado. Cada aplicación tiene un limitado presupuesto de tiempo para refrescar su contenido en segundo plano. En otras palabras, complicaciones no son un remplazo para empujar notificaciones o el centro de notificaciones.
El principal beneficio de proporcionar datos de ésta forma es mantener una excelente experiencia de usuario. El contenido para cada complicación está inmediatamente disponible cuando el usuario levanta su muñeca. Uno de los otros beneficios de usar éste modelo de datos de la línea de tiempo es la capacidad de adoptar fácilmente la nueva característica Time Travel en watchOS 2. Ésto es cuando el usuario voltea la corona digital mientras observa la carátula y los datos de las complicaciones reflejan el tiempo al que ha viajado.
En tu código, bajo la marca Timeline Configuration, verás cuatro métodos que son requeridos para configurar el timeline. Para hacer éste tutorial sencillo y fácil de entender, sólo vamos a soportar viaje de tiempo hacia adelante y proporcionar datos por hasta 24 horas. Para hacer ésto, actualizamos la implementación de los primeros tres métodos como se muestra debajo.
1 |
func getSupportedTimeTravelDirectionsForComplication(complication: CLKComplication, withHandler handler: (CLKComplicationTimeTravelDirections) -> Void) { |
2 |
handler(.Forward) |
3 |
}
|
4 |
|
5 |
func getTimelineStartDateForComplication(complication: CLKComplication, withHandler handler: (NSDate?) -> Void) { |
6 |
handler(NSDate()) |
7 |
}
|
8 |
|
9 |
func getTimelineEndDateForComplication(complication: CLKComplication, withHandler handler: (NSDate?) -> Void) { |
10 |
handler(NSDate(timeIntervalSinceNow: (60 * 60 * 24))) |
11 |
}
|
El cuarto método en la sección Timeline Configuration, getPrivacyBehaviorForComplication(_:withHandler:)
, es usado para especificar si quieres o no que el contenido de tu complicación se muestre cuando el dispositivo está bloqueado o no. El valor predeterminado pasado al manejador, ShowOnLockScreen
, significa que los datos siempre serán visibles.
Plantillas
Haz scroll hasta la parte inferior de la clase ComplicationController
y encuentra el método getPlaceHolderTemplateForComplication(_:withHandler)
En éste método, creas y pasas un CLKComplicationTemplate
de vuelta al manejador para los datos que quieres mostrar. En éste tutorial, vas a usar la plantilla CLKComplicationTemplateModularLargeStandardBody
, que muestra tres líneas de texto. Para cada programa de televisión, éstas tres líneas van a ser:
- tiempo de inicio y fin
- nombre
- género
Hay pocas plantillas disponibles en las cinco familias de complicaciones. La siguiente imagen muestra las plantillas disponibles y resalta la que vamos a usar en éste tutorial.



Proveedores de Texto
Porque el espacio para el contenido es limitado en un desplegado de reloj, aún más en los tamaños pequeños en las complicaciones de carátulas, proporcionas datos basados en texto a ClockKit, usando objetos CLKTextProvider
. Éstos proveedores tienen como objetivo evitar truncar contenido, lo cual resulta en una mala experiencia de usuario. Con éstos proveedores de texto, describes tus intenciones sobre que contenido quieres mostrar y luego ClockKit maneja el formato final por tí.
Por ejemplo, si quieres mostrar una fecha en tu complicación, usas el CLKDateTextProvider
con una fecha específica y conjunto de unidades (mes, día, hora, etc.). Eso dará el correcto formato a la fecha para el espacio disponible. Un ejemplo de ésto sería tomar la fecha "Jueves, Octubre 22" y poder darle el formato de:
- Jue, Octubre 22
- Jue, Oct 22
- Oct 22
- 22
Para una lista completa de proveedores de texto y plantillas disponibles en ClockKit, puedes ver la Guía del Framework ClockKit de Apple.
Ahora que sabes de las plantillas y los proveedores de texto básicos, estás listo para crear una plantilla para tu complicación. En el método getPlaceHolderTemplateForComplication(_:withHandler)
, agrega el siguiente código:
1 |
func getPlaceholderTemplateForComplication(complication: CLKComplication, withHandler handler: (CLKComplicationTemplate?) -> Void) { |
2 |
// This method will be called once per supported complication, and the results will be cached
|
3 |
let template = CLKComplicationTemplateModularLargeStandardBody() |
4 |
|
5 |
template.headerTextProvider = CLKTimeIntervalTextProvider(startDate: NSDate(), endDate: NSDate(timeIntervalSinceNow: 60 * 60 * 1.5)) |
6 |
template.body1TextProvider = CLKSimpleTextProvider(text: "Show Name", shortText: "Name") |
7 |
template.body2TextProvider = CLKSimpleTextProvider(text: "Show Genre", shortText: nil) |
8 |
|
9 |
handler(template) |
10 |
}
|
Con éste código, creas una plantilla Standard Body para la familia Modular Large y le das tres proveedores de texto. Los objetos CLKSimpleTextProvider
deben ser sencillos. El CLKTimeIntervalTextProvider
toma dos fechas y les da formato a string, tal como "10:00 AM-3:30PM" o "1:00-2:45PM".
3. Probar la Complicación
Ahora que hemos configurado nuestra línea de tiempo y proporcionado a ClockKit una plantilla para nuestra complicación, podemos finalmente probar los resultados de nuestro trabajo. En la parte superior izquierda de tu ventana de Xcode, elige el target de tu complicación y uno de los simuladores disponibles. Da click en el botón de play para compilar y ejecutar tu aplicación.



Cuando el simulador de Apple Watch se lanza, probablemente verás la siguiente carátula:



Para probar tu complicación, necesitas completar unos cuantos pasos.
Paso 1
Presiona Command+Mayúsculas+2 para simular un toque de fuerza y da click en la carátula.



Paso 2
Presiona Command+Mayúsculas+1, desplázate a la derecha a la carátula de Modular y da click en el botón Customize.



Paso 3
Desplázate a la derecha, pulsa la complicación de en medio, y haz scroll hacia abajo, usando tu trackpad o ratón para simular la corona digital.



Paso 4
Simula un toque de fuerza de nuevo para regresar al seleccionador de carátulas y selecciona Modular.



Felicitaciones. Tienes tu primera complicación ClockKit para mostrar en una carátula de Apple Watch. Ahora es momento para que inicies el llenado con datos reales.
4. Proporcionar Datos a ClockKit
Antes de que creemos cualquier entrada de timeline para tu complicación, primero vamos a crear un struct (estructura) Show
para modelar fácilmente nuestros datos y luego crear valores de éste nuevo tipo. Agrega el siguiente fragmento de código a ComplicationController.swift, antes del inicio de la definición de la clase ComplicationController
.
1 |
struct Show { |
2 |
var name: String |
3 |
var shortName: String? |
4 |
var genre: String |
5 |
|
6 |
var startDate: NSDate |
7 |
var length: NSTimeInterval |
8 |
}
|
9 |
|
10 |
let hour: NSTimeInterval = 60 * 60 |
11 |
let shows = [ |
12 |
Show(name: "Into the Wild", shortName: "Into Wild", genre: "Documentary", startDate: NSDate(), length: hour * 1.5), |
13 |
Show(name: "24/7", shortName: nil, genre: "Drama", startDate: NSDate(timeIntervalSinceNow: hour * 1.5), length: hour), |
14 |
Show(name: "How to become rich", shortName: "Become Rich", genre: "Documentary", startDate: NSDate(timeIntervalSinceNow: hour * 2.5), length: hour * 3), |
15 |
Show(name: "NET Daily", shortName: nil, genre: "News", startDate: NSDate(timeIntervalSinceNow: hour * 5.5), length: hour) |
16 |
]
|
Como puedes ver, creamos la estructura Show
y creamos un array (arreglo) estático que contiene cuatro shows (programas). Usarás éste arreglo como la fuente de datos de tu complicación.
En la clase ComplicationController
, encuentra el método getCurrentTimelineEntryForComplication(_:withHandler)
y agrégale el siguiente código:
1 |
func getCurrentTimelineEntryForComplication(complication: CLKComplication, withHandler handler: ((CLKComplicationTimelineEntry?) -> Void)) { |
2 |
// Call the handler with the current timeline entry
|
3 |
|
4 |
let show = shows[0] |
5 |
let template = CLKComplicationTemplateModularLargeStandardBody() |
6 |
|
7 |
template.headerTextProvider = CLKTimeIntervalTextProvider(startDate: show.startDate, endDate: NSDate(timeInterval: show.length, sinceDate: show.startDate)) |
8 |
template.body1TextProvider = CLKSimpleTextProvider(text: show.name, shortText: show.shortName) |
9 |
template.body2TextProvider = CLKSimpleTextProvider(text: show.genre, shortText: nil) |
10 |
|
11 |
let entry = CLKComplicationTimelineEntry(date: NSDate(timeInterval: hour * -0.25, sinceDate: show.startDate), complicationTemplate: template) |
12 |
handler(entry) |
13 |
}
|
Primero crea una plantilla de complicación, como lo hiciste antes, y llénala de contenido. Luego crea un objeto CLKComplicationTimelineEntry
con dos parámetros:
- una fecha
- una plantilla
La fecha que especificas aquí es donde se posicionará ésta entrada en el timeline y se mostrará al usuario. Para nuestra aplicación, damos a nuestra entrada de timeline una fecha de quince minutos antes del inicio estipulado del show, así que se mostrará en la carátula del usuario antes de que inicie el show.
Posteriormente, necesitas proporcionar a ClockKit todos los otros shows que has creado para tu complicación. Ésto se hace en el método getTimelineEntriesForComplication(_:afterDate:limit)
El parámetro límite en éste método está ahí para que una sola aplicación no pueda sobrecargar el cache de ClockKit con datos y sabe exactamente cuántas entradas de timeline necesita proporcionar.
Agrega el siguiente cóidgo al método getTimelineEntriesForComplication(_:afterDate:limit)
en ComplicationController.swift:
1 |
func getTimelineEntriesForComplication(complication: CLKComplication, afterDate date: NSDate, limit: Int, withHandler handler: (([CLKComplicationTimelineEntry]?) -> Void)) { |
2 |
// Call the handler with the timeline entries after to the given date
|
3 |
|
4 |
var entries: [CLKComplicationTimelineEntry] = [] |
5 |
|
6 |
for show in shows |
7 |
{
|
8 |
if entries.count < limit && show.startDate.timeIntervalSinceDate(date) > 0 |
9 |
{
|
10 |
let template = CLKComplicationTemplateModularLargeStandardBody() |
11 |
|
12 |
template.headerTextProvider = CLKTimeIntervalTextProvider(startDate: show.startDate, endDate: NSDate(timeInterval: show.length, sinceDate: show.startDate)) |
13 |
template.body1TextProvider = CLKSimpleTextProvider(text: show.name, shortText: show.shortName) |
14 |
template.body2TextProvider = CLKSimpleTextProvider(text: show.genre, shortText: nil) |
15 |
|
16 |
let entry = CLKComplicationTimelineEntry(date: NSDate(timeInterval: hour * -0.25, sinceDate: show.startDate), complicationTemplate: template) |
17 |
entries.append(entry) |
18 |
}
|
19 |
}
|
20 |
|
21 |
handler(entries) |
22 |
}
|
Primero creas un arreglo vacío de objetos CLKComplicationTimelineEnry
. Luego iteras a través de los shows que creaste previamente. Para cada show, si empieza después de la fecha proporcionada por ClockKit y el límite de entradas no ha sido excedido, entonces creas una plantilla y agregas ésta al arreglo.
Al final de éste método, llamas al manejador con tu arreglo. Pasándole nil
o un arreglo vacío al manejador dirá a ClockKit que no tienes más datos que proporcionar y dejará de consultar tu objeto CLKComplicationDataSource
hasta que se requieran más datos.
Con éstos métodos en su lugar, ahora estás listo para ver tu complicación terminada. Da click en el botón play para compilar y ejecutar tu aplicación. Cuando el simulador se lanza, verás tu complicación que muestra los datos del primer show que creaste.



Si haces scroll con tu trackpad o ratón para ingresar el modo Time Travel, verás que los otros shows que creaste son mostrados por tu complicación en el punto correcto en el tiempo.



Conclusión
En éste tutorial, aprendiste los fundamentos del framework ClockKit y cómo crear una complicación personalizada en la carátula para el Apple Watch. Ésto incluyó las cinco familias de complicación, plantillas básicas y proveedores de texto, y datos basados en la línea de tiempo.
En tu complicación, también integraste soporte para la característica viaje en el tiempo de watchOS 2 y agregaste nuevos datos mientras el tiempo prosigue. Como siempre, si tienes algún comentario o pregunta, déjalos en la sección de comentarios abajo.
¡Sé el primero en conocer las nuevas traducciones–sigue @tutsplus_es en Twitter!