ios - salud - apple watch lte colombia
Pasar datos a la aplicación Apple Watch (4)
Como dijo @johndpope, los NSUserDefaults compartidos ya no funcionan en WatchOS2.
Estoy publicando una solución simplificada que no es tan completa como la de John pero que hará el trabajo en la mayoría de los casos.
En su aplicación para iPhone , siga estos pasos:
Elija encontrar el controlador de vista desde el que desea enviar datos al Apple Watch y agregue el marco en la parte superior.
import WatchConnectivity
Ahora, establezca una sesión WatchConnectivity con el reloj y envíe algunos datos.
if WCSession.isSupported() { //makes sure it''s not an iPad or iPod
let watchSession = WCSession.defaultSession()
watchSession.delegate = self
watchSession.activateSession()
if watchSession.paired && watchSession.watchAppInstalled {
do {
try watchSession.updateApplicationContext(["foo": "bar"])
} catch let error as NSError {
print(error.description)
}
}
}
Tenga en cuenta que esto NO funcionará si omite la configuración del delegado, por lo que incluso si nunca lo usa, debe configurarlo y agregar esta extensión:
extension MyViewController: WCSessionDelegate {
}
Ahora, en su aplicación de reloj (este código exacto funciona para Glances y otros tipos de aplicaciones de kit de reloj también), agregue el marco:
import WatchConnectivity
Luego configura la sesión de conectividad:
override func awakeWithContext(context: AnyObject?) {
super.awakeWithContext(context)
let watchSession = WCSession.defaultSession()
watchSession.delegate = self
watchSession.activateSession()
}
y simplemente escuchas y manejas los mensajes de la aplicación iOS:
extension InterfaceController: WCSessionDelegate {
func session(session: WCSession, didReceiveApplicationContext applicationContext: [String : AnyObject]) {
print("/(applicationContext)")
dispatch_async(dispatch_get_main_queue(), {
//update UI here
})
}
}
Eso es todo al respecto.
Artículos de nota:
- Puede enviar un nuevo contexto de aplicación tantas veces como lo desee y no importa si el reloj está cerca y conectado o si la aplicación de reloj se está ejecutando. Esto entrega los datos en segundo plano de una manera inteligente y esos datos están allí esperando mientras se inicia la aplicación del reloj.
- Si su aplicación de reloj está realmente activa y ejecutándose, debería recibir el mensaje inmediatamente en la mayoría de los casos.
- Puede revertir este código para que el reloj envíe mensajes a la aplicación de iPhone de la misma manera.
- applicationContext que su aplicación de reloj recibe cuando se ve SÓLO será el último mensaje que envió. Si envió 20 mensajes antes de ver la aplicación de reloj, ignorará los primeros 19 y manejará el 20.
- Para hacer una conexión directa / dura entre las 2 aplicaciones o para transferencias de archivos en segundo plano o mensajes en cola, mira el video WWDC .
Estoy tratando de pasar datos de mi aplicación a mi aplicación Apple Watch. Básicamente, estoy usando el mismo método que usé para crear el widget de hoy y, por lo tanto, estoy pasando datos a través de NSUserDefaults.
El problema es que cuando ejecuto mi aplicación, los datos no actualizan las etiquetas en la aplicación Watch como lo esperaría.
Esto es lo que tengo ...
override init(context: AnyObject?) {
// Initialize variables here.
super.init(context: context)
// Configure interface objects here.
NSLog("%@ init", self)
var defaults = NSUserDefaults(suiteName: "group.AffordIt")
var totalBudgetCalculation = ""
if (defaults!.stringForKey("totalBudgetWidget") != nil) {
println("Worked")
totalBudgetCalculation = defaults!.stringForKey("totalBudgetWidget")!
initialBudgetLabel.setText("Initial: /(totalBudgetCalculation)")
}
var currentBudgetCalculation = ""
if (defaults!.stringForKey("currentBudgetWidget") != nil) {
currentBudgetCalculation = defaults!.stringForKey("currentBudgetWidget")!
currentBudgetLabel.setText("Current: /(currentBudgetCalculation)")
}
}
Intenté poner este código en
willActivate()
, sin embargo, eso no parece hacer la diferencia.
Alguien sabe a dónde voy mal?
La respuesta aceptada se aplica a Apple Watch OS 1. Ver NSUserDefaults no funciona en Xcode beta con Watch OS2
Para OS2: deberá usar los marcos de WatchConnectivity e implementar WCSessionDelegate.
import WatchConnectivity
import WatchKit
@available(iOS 9.0, *)
var alertDelegate:HomeIC? = nil
public class WatchData: NSObject,WCSessionDelegate {
var session = WCSession.defaultSession()
//
class var shared: WatchData {
struct Static {
static var onceToken: dispatch_once_t = 0
static var instance: WatchData? = nil
}
dispatch_once(&Static.onceToken) {
Static.instance = WatchData()
}
return Static.instance!
}
public func session(session: WCSession, didReceiveFile file: WCSessionFile){
print(__FUNCTION__)
print(session)
}
public func session(session: WCSession, didReceiveApplicationContext applicationContext: [String : AnyObject]) {
print(__FUNCTION__)
print(session)
alertDelegate?.showMessage("didReceiveApplicationContext")
}
public func sessionReachabilityDidChange(session: WCSession){
print(__FUNCTION__)
print(session)
print("reachability changed:/(session.reachable)")
let text = session.reachable ? "reachable" : "unreachable"
alertDelegate?.showMessage(text)
}
public func sessionWatchStateDidChange(session: WCSession) {
print(__FUNCTION__)
print(session)
print("reachable:/(session.reachable)")
// alertDelegate?.showMessage("sessionWatchStateDidChange")
if !session.receivedApplicationContext.keys.isEmpty {
alertDelegate?.showMessage(session.receivedApplicationContext.description)
}
}
public func session(session: WCSession, didReceiveMessageData messageData: NSData){
if !session.receivedApplicationContext.keys.isEmpty {
alertDelegate?.showMessage(session.receivedApplicationContext.description)
}
}
public func session(session: WCSession, didReceiveMessage message: [String : AnyObject]){
print(__FUNCTION__)
if let data = message["data"] {
alertDelegate?.showMessage(data as! String)
return
}
}
public func session(session: WCSession, didReceiveMessage message: [String : AnyObject], replyHandler: ([String : AnyObject]) -> Void) {
print(__FUNCTION__)
if let data = message["data"] {
alertDelegate?.showMessage(data as! String)
return
}
guard message["request"] as? String == "showAlert" else {return}
}
public func activate(){
if WCSession.isSupported() { // it is supported
session = WCSession.defaultSession()
session.delegate = self
session.activateSession()
print("watch activating WCSession")
} else {
print("watch does not support WCSession")
}
if(!session.reachable){
print("not reachable")
return
}else{
print("watch is reachable")
}
}
}
Uso de muestra
class HomeIC: WKInterfaceController {
// MARK: Properties
override func awakeWithContext(context: AnyObject?) {
super.awakeWithContext(context)
// Initialize the `WCSession`.
WatchData.shared.activate()
alertDelegate = self
}
internal func showMessage(msg:String){
let defaultAction = WKAlertAction(title: msg, style: WKAlertActionStyle.Default) { () -> Void in }
let actions = [defaultAction]
self.presentAlertControllerWithTitle( "Info", message: "", preferredStyle: WKAlertControllerStyle.Alert, actions: actions)
}
}
en mi código de iPhone / puedo invocar el intercambio de datos aquí
if #available(iOS 9.0, *) {
WatchData.shared.sendInbox()
} else {
// Fallback on earlier versions
}
Y en otro lugar tengo otro singleton discreto para ver la sesión de datos.
@available(iOS 9.0, *)
public class WatchData: NSObject,WCSessionDelegate {
var session = WCSession.defaultSession()
var payload:String = ""
class var shared: WatchData {
struct Static {
static var onceToken: dispatch_once_t = 0
static var instance: WatchData? = nil
}
dispatch_once(&Static.onceToken) {
Static.instance = WatchData()
}
return Static.instance!
}
public func sessionReachabilityDidChange(session: WCSession){
print(__FUNCTION__)
print(session)
print("reachability changed:/(session.reachable)")
if (session.reachable){
}
}
public func sessionWatchStateDidChange(session: WCSession) {
print(__FUNCTION__)
print(session)
print("reachable:/(session.reachable)")
}
public func session(session: WCSession, didReceiveMessage message: [String : AnyObject], replyHandler: ([String : AnyObject]) -> Void) {
print(__FUNCTION__)
guard message["request"] as? String == "showAlert" else {return}
guard let m = message["m"] as? String else { return }
print("msg:",m)
}
public func sendInbox(){
if (!session.reachable){
if WCSession.isSupported() { // it is supported
session = WCSession.defaultSession()
session.delegate = self
session.activateSession()
print("iphone activating WCSession")
} else {
print("iphone does not support WCSession")
}
session.activateSession()
}
if(session.paired){
if(session.watchAppInstalled){
print("paired | watchAppInstalled")
}
}else{
print("not paired | or no watchAppInstalled")
}
if(!session.reachable){
print("not reachable")
return
}else{
/*let transfer:WCSessionUserInfoTransfer = (session.transferUserInfo(["data" : "Test2"]) as WCSessionUserInfoTransfer?)!
if(transfer.transferring){
print("-> iphone")
}else{
print("!-> iphone")
}*/
session.sendMessage(["data" :"test"],
replyHandler: { reply in
},
errorHandler: { error in
print(error)
})
}
}
}
Consulte la aplicación de muestra de reloj os2
https://github.com/shu223/watchOS-2-Sampler/tree/20eeebeed66764d0814603e97d3aca5933236299
Otra forma de comunicarse entre la aplicación y el reloj es a través del agujero de gusano:
https://github.com/mutualmobile/MMWormhole
Enviar:
[self.wormhole passMessageObject:@{@"titleString" : title}
identifier:@"messageIdentifier"];
id messageObject = [self.wormhole messageWithIdentifier:@"messageIdentifier"];
Recibir:
[self.wormhole listenForMessageWithIdentifier:@"messageIdentifier"
listener:^(id messageObject) {
// Do Something
}];
Esto se aplica solo al sistema operativo 1. Vea a continuación para obtener mejores respuestas.
Lo hice funcionar usando tu método. Supongo que hay un par de cosas que puedes verificar:
1) ¿Está sincronizando los valores predeterminados después de establecer el valor:
defaults?.synchronize();
NSLog("%@ ", defaults?.dictionaryRepresentation())
2) ¿Ha habilitado el grupo de aplicaciones tanto en su aplicación como en su extensión?
3) ¿Está utilizando el grupo de aplicaciones con el nombre correcto al construir los NSDefaults? Por ejemplo, yo uso:
NSUserDefaults(suiteName: "group.com.brindysoft.MyWatch");
Una vez que todo está configurado, ejecuto la aplicación, establezco el valor en los valores predeterminados, luego ejecuto el objetivo de mirada que lee el valor predeterminado y ¡parece que funciona!
- ¿Todavía atascado? verifique sus grupos de aplicaciones en su cuenta de Apple