将数据传递给Apple Watch应用程序

我试图从我的应用程序传入数据到我的Apple Watch应用程序。 基本上,我使用的方法与创build当前小部件的方法相同,所以我通过NSUserDefaults传递数据。

问题是,当我运行我的应用程序时,数据不会像我所期望的那样更新Watch应用程序中的标签。

这是我有…

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)") } } 

我试着把这个代码放在willActivate() ,但是这似乎没有什么区别。

任何人都知道我要去哪里错了?

我用你的方法得到了它的工作。 我想有几件事你可以检查:

1)在设置值之后是否同步默认值:

 defaults?.synchronize(); NSLog("%@ ", defaults?.dictionaryRepresentation()) 

2)您是否在应用程序和扩展中启用了应用程序组?

应用目标的应用组功能手表扩展目标的应用组功能

3)构buildNSDefaults时是否使用了正确命名的应用程序组? 例如,我使用:

 NSUserDefaults(suiteName: "group.com.brindysoft.MyWatch"); 

一旦完成所有设置,我运行应用程序,设置默认值,然后运行扫描目标,从默认值读取值,似乎工作!

在这里输入图像说明

  1. 仍然卡住? 检查你的苹果帐户中的应用程序组

接受的答案适用于苹果手表操作系统1.请参阅NSUserDefaults不能在Watch OS2的Xcodetesting版上工作

对于OS2 – 您将需要使用WatchConnectivity框架并实现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") } } } 

样例用法

 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) } } 

在这里输入图像说明

在我的iPhone代码/我可以在这里调用共享数据

  if #available(iOS 9.0, *) { WatchData.shared.sendInbox() } else { // Fallback on earlier versions } 

而在别的地方,我还有另外一个独立的单独的手表数据会话。

 @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) }) } } } 

请参阅示例手表os2应用程序

https://github.com/shu223/watchOS-2-Sampler/tree/20eeebeed66764d0814603e97d3aca5933236299

正如@johndpope所说,共享NSUserDefaults不再适用于WatchOS2。

我发布了一个简化的解决scheme,不像约翰那样function齐全,但在大多数情况下都能完成工作。

在你的iPhone App中 ,按照下列步骤操作:

selectfind您想要将数据推送到Apple Watch的视图控制器,然后在顶部添加框架。

 import WatchConnectivity 

现在,与手表build立WatchConnectivity会话并发送一些数据。

 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) } } } 

请注意,如果你跳过设置委托,这将不起作用,所以即使你从不使用它,你必须设置它并添加这个扩展:

 extension MyViewController: WCSessionDelegate { } 

现在,在你的手表应用程序 (这个确切的代码适用于Glances和其他手表套件应用程序types以及),你添加框架:

 import WatchConnectivity 

然后你build立连接会话:

 override func awakeWithContext(context: AnyObject?) { super.awakeWithContext(context) let watchSession = WCSession.defaultSession() watchSession.delegate = self watchSession.activateSession() } 

你只需要听取和处理来自iOS应用程序的消息:

 extension InterfaceController: WCSessionDelegate { func session(session: WCSession, didReceiveApplicationContext applicationContext: [String : AnyObject]) { print("\(applicationContext)") dispatch_async(dispatch_get_main_queue(), { //update UI here }) } } 

这里的所有都是它的。

注意事项:

  1. 您可以随时发送新的applicationContext,无论手表是在附近并连接还是在手表应用程序运行。 这将以智能的方式在后台传输数据,并且在手表应用程序启动时数据就在那里等待。
  2. 如果您的手表应用程序确实处于活动状态并正在运行,则应在大多数情况下立即收到该信息
  3. 您可以反转此代码,让手表以相同的方式将消息发送到iPhone应用程序。
  4. 您的手表应用程序在查看时收到的applicationContext将只是您发送的最后一条消息。 如果您在查看手表应用程序之前发送了20条消息,则会忽略前19条并处理第20条消息。
  5. 要在两个应用程序之间进行直接/硬连接,或进行后台文件传输或排队消息,请查看WWDCvideo 。

应用程序和手表之间的另一种沟通方式是通过虫洞:

https://github.com/mutualmobile/MMWormhole

发送:

 [self.wormhole passMessageObject:@{@"titleString" : title} identifier:@"messageIdentifier"]; id messageObject = [self.wormhole messageWithIdentifier:@"messageIdentifier"]; 

收到:

 [self.wormhole listenForMessageWithIdentifier:@"messageIdentifier" listener:^(id messageObject) { // Do Something }];