Spanish (Español) translation by Javier Salesi (you can also view the original English article)
Desde el lanzamiento del Apple Watch, los desarrolladores han estado debatiendo y presentando técnicas para superar las limitaciones de watchOS 1. Desarrolladores se han preguntado, por ejemplo, cómo establecer confiadamente una comunicación entre una aplicación watchOS y su aplicación padre iOS, y viceversa.
Un número de soluciones han estado disponibles para resolver éste problema como MMWormhole. Claro, Apple ha sido muy consciente de las limitaciones de watchOS 1 y el lanzamiento de watchOS 2 resuelve un número de las limitaciones de watchOS 1. Comunicarse entre una aplicación watchOS 2 y su aplicación padre iOS, por ejemplo, se ha hecho más simple gracias a la introducción del framework Watch Connectivity.
Watch Connectivity
El framework Watch Connectivity proporciona varias maneras de comunicación entre una aplicación iOS y una watchOS 2. Con el framework Watch Connectivity, puedes actualizar la información en un contraparte, enviar mensajes, transferir datos en segundo plano, e incluso transferir archivos. Para aprender más de las características y capacidades del framework, recomiendo leer la documentación de Apple para el framework Watch Connectivity.
En éste tutorial, te mostraré como intercambiar datos entre una aplicación watchOS 2 y su aplicación padre iOS, y viceversa. La API que usaremos para lograr ésto es sendMessage(_:replyHandler:errorHandler:)
. Éste método permite a los desarrolladores transferir datos entre la aplicación watchOS 2 y su aplicación padre iOS.
Es importante notar que la aplicación iOS y la aplicación watchOS 2 responden de manera diferente cuando es invocado sendMessage(_:replyHandler:errorHandler:)
. Si éste método es invocado por la aplicación watchOS 2, la aplicación iOS será avisada por el sistema operativo. Si mandas datos desde la aplicación padre iOS a la aplicación watchOS 2, sin embargo, la última no recibirá un aviso. Éste es un detalle importante para tener en cuenta.
Requisitos Previos
Ya que éste tutorial es sobre desarrollo del Apple Watch, asumo que ya estás familiarizado con el desarrollo iOS y el lenguaje de programación Swift. El framework Watch Connectivity está solo disponible en watchOS 2, lo cual significa que necesitas tener la versión más reciente de Xcode instalada, Xcode 7. Puedes descargar Xcode desde el sitio web del desarrollador de Apple.
1. Creación del Proyecto
Abre Xcode y selecciona New > Project... del menú File. Ve a watchOS > Application, selecciona la plantilla de proyecto iOS App with WatchKit App y da click en Next. Nombra tu aplicación SendMessageWatch, establece Language en Swift, y Devices en iPhone. Desmarca Include Notification Scene y asegúrate que cada casilla de verificación en la parte inferior esté desmarcada. Pulsa Next y elige una ubicación para guardar tu proyecto.



2. Creando la Interfaz de Usuario
En éste paso, agregaremos una etiqueta y un botón a ambas aplicaciones. La etiqueta será usada para desplegar los mensajes que estamos enviando mientras el botón enviará el mensaje a la contraparte, la aplicación iOS o la aplicación watchOS 2.
Comenzaremos con la aplicación iOS. Abre Main.storyboard y agrega una etiqueta y un botón. Luego, crea un outlet para ambos elementos de la interfaz de usuario, y agrega una acción para el botón. La captura de pantalla de abajo muestra el resultado.



Ahora enfoquémonos en la aplicación watchOS 2. Abre Interface.storyboard y agrega una etiqueta y un botón a la escena. Posteriormente, abre InterfaceController.swift en el Assistant Editor y crea un outlet para la etiqueta y el botón, y agrega una acción para el botón.



Con la interfaz de usuario instalaa, es momento de adentrarnos en el tópico principal, enviar mensajes desde la aplicación iOS a la aplicación watchOS 2, y viceversa.
3. Usando el Framework Watch Connectivity
Utilizar el framework Watch Connectivity para intercambiar mensajes requiere el uso de la clase WCSession
. Para que ésto funcione, tanto la aplicación iOS como la aplicación watchOS 2 deben crear y configurar una instancia WCSession
. Cuando la sesión es configurada, podemos comunicarnos inmediatamente de un lado a otro.
class InterfaceController: WKInterfaceController,WCSessionDelegate{ var session : WCSession! ... }
Obtenemos una instancia de la clase WCSession
al llamar al método de la clase defaultSession
. Éste regresa el objeto session singleton (de instancia única) para el dispositivo. Necesitamos entonces establecer el delegado de la sesión y activar la sesión.
Antes de que configuremos y usemos el objeto WCSession
, necesitamos verificar que la clase WCSession
es soportada en el dispositivo. Hacemos ésto al llamar al método de la clase isSupported
en la clase WCSession
. Hacemos todo ésto en el método willActivate
de la clase InterfaceController
. Nota que activateSession
arrojará una excepción si el delegado de la sesión es nil
. En otras palabras, el orden de las instrucciones de abajo es importante.
override func willActivate() { super.willActivate() if (WCSession.isSupported()) { session = WCSession.defaultSession() session.delegate = self session.activateSession() } }
La aplicación watchOS 2 puede ahora enviar y recibir mensajes. Con la sesión activada, solo necesitamos invocar al método sendMessage(_:replyHandler:errorHandler:)
para enviar mensajes. El primer argumento necesita ser un diccionario de tipo [String :AnyObject]
y no debería ser nil
.
El replyHandler
es una clausura que acepta un diccionario del mismo tipo. Éste diccionario es la respuesta de la contraparte. El errorHandler
también es una clausura, que puede ser nil
si no necesitas capturar ningún error.
Si pulsamos el botón de enviar en el Apple Watch, inmediatamente enviará un mensaje Hello iPhone y el iPhone responderá con un mensaje Hello Watch. Después de pulsar el botón enviar en el iPhone, enviará una pregunta Hi watch, can you talk to me? (Hola reloj, ¿Puedes hablar conmigo?) y el Apple Watch responderá Yes (Si).
Así se debería ver la implementación del método sendMessage
en InterfaceController.swift.
@IBAction func sendMessage() { let messageToSend = ["Value":"Hello iPhone"] session.sendMessage(messageToSend, replyHandler: { replyMessage in //handle and present the message on screen let value = replyMessage["Value"] as? String self.messageLabel.setText(value) }, errorHandler: {error in // catch any errors here print(error) }) }
Para manejar el mensaje en el dispositivo iOS, necesitamos implementar el método delegado session(_:didReceiveMessage:)
del protocolo WCSessionDelegate
, que es invocado cuando un mensaje es recibido por la contraparte. Asi se ve la implementación en InterfaceController.swift.
func session(session: WCSession, didReceiveMessage message: [String : AnyObject], replyHandler: ([String : AnyObject]) -> Void) { //handle received message let value = message["Value"] as? String //use this to present immediately on the screen dispatch_async(dispatch_get_main_queue()) { self.messageLabel.setText(value) } //send a reply replyHandler(["Value":"Yes"]) }
La implementación de ambos métodos se ve muy similar a la aplicación iOS. Con las implementaciones de arriba, intenta implementar los métodos sendMessage
y session(_:didReceiveMessage:replyHandler:)
. Asi se debería ver la implementación de la clase ViewController
.
import UIKit import WatchConnectivity class ViewController: UIViewController, WCSessionDelegate { var session: WCSession! @IBOutlet var messageLabel: UILabel! @IBOutlet var sendButton: UIButton! @IBAction func sendMessage(sender: AnyObject) { //Send Message to WatchKit let messageToSend = ["Value":"Hi watch, can you talk to me?"] session.sendMessage(messageToSend, replyHandler: { replyMessage in //handle the reply let value = replyMessage["Value"] as? String //use dispatch_asynch to present immediately on screen dispatch_async(dispatch_get_main_queue()) { self.messageLabel.text = value } }, errorHandler: {error in // catch any errors here print(error) }) } override func viewDidLoad() { super.viewDidLoad() // Do any additional setup after loading the view, typically from a nib. if (WCSession.isSupported()) { session = WCSession.defaultSession() session.delegate = self; session.activateSession() } } override func didReceiveMemoryWarning() { super.didReceiveMemoryWarning() // Dispose of any resources that can be recreated. } //Swift func session(session: WCSession, didReceiveMessage message: [String : AnyObject], replyHandler: ([String : AnyObject]) -> Void) { //handle received message let value = message["Value"] as? String dispatch_async(dispatch_get_main_queue()) { self.messageLabel.text = value } //send a reply replyHandler(["Value":"Hello Watch"]) } }
Compila y ejecuta las aplicaciones para ver el resultado final. Cuando presionas el botón en el Apple Watch, un mensaje debería aparecer en el iPhone asociado ejecutando la aplicación iOS. Cuando presionas el botón de la aplicación iOS, un mensaje deberia aparecer en el Apple Watch ejecutando la aplicación watchOS 2.



4. Explorando el Protocolo WCSessionDelegate
El método delegado que implementamos para recibir el mensaje tiene un hermano más simple, session(_:didReceiveMessage:)
. Éste método es llamado cuando sendMessage(_:replyHandler:errorHandler:)
es invocado sin un reply handler. Ésto simplemente indica que la aplicación que envía el mensaje no espera una respuesta.
Además de enviar un diccionario a un contraparte, también es posible enviar un objeto NSData
usando el método sendMessageData(_:replyHandler:errorHandler:)
. La contraparte recibe el mensaje a través de los métodos delegados session(_:didReceiveMessageData:)
y session(_:didReceiveMessageData:replyHandler:)
del protocolo WCSessionDelegate
.
Conclusión
Si necesitas comunicarte inmediatamente con un contraparte, entonces el framework Watch Connectivity es la mejor elección en el watchOS 2. Los mensajes hacen fila y son entregados en el mismo orden en el que fueron enviados.
El framework Watch Connectivity tiene mucho más que ofrecer de lo que se cubrió en éste tutorial. En futuros tutoriales, conoceremos más a detalle éste framework para explorar sus características y capacidades.
¡Sé el primero en conocer las nuevas traducciones–sigue @tutsplus_es en Twitter!
Subscribe below and we’ll send you a weekly email summary of all new Code tutorials. Never miss out on learning about the next big thing.
Update me weekly