11

最近,我又在做一个与Watch/iPhone通讯有关的项目。但是我的代码有时有效,有时无效,这对我来说有点奇怪,因为我认为代码应该有效或无效。它不能是 50/50。因此,我不知道出了什么问题。

在 iPhone 上设置 WCSession:

class WatchCommunicationController: NSObject, WCSessionDelegate {

    var session : WCSession?

    override init(){

        //  super class init
        super.init()

        //  if WCSession is supported
        if WCSession.isSupported() {    //  it is supported

            //  get default session
            session = WCSession.defaultSession()

            //  set delegate
            session!.delegate = self

            //  activate session
            session!.activateSession()

        } else {

            print("iPhone does not support WCSession")
        }
    }

    ... ...
}

Watch 上类似的 WCSession 设置:

class PhoneCommunicationController: NSObject, WCSessionDelegate {

    var session : WCSession?

    override init(){

        //  super class init
        super.init()

        //  if WCSession is supported
        if WCSession.isSupported() {    //  it is supported

            //  get default session
            session = WCSession.defaultSession()

            //  set delegate
            session!.delegate = self

            //  activate session
            session!.activateSession()
        } else {

            print("Watch does not support WCSession")
        }
    }

    ... ...
}

在 Watch 上发送消息:

func sendGesture(手势:GKGesture){

//  if WCSession is reachable
if session!.reachable {     //  it is reachable

    //  create the interactive message with gesture
    let message : [String : AnyObject]
    message = [
                "Type":"Gesture",
                "Content":gesture.rawValue
              ]

    //  send message
    session!.sendMessage(message, replyHandler: nil, errorHandler: nil)
    print("Watch send gesture \(gesture)")

} else{                     //  it is not reachable

    print("WCSession is not reachable")
}

}

相关枚举:

enum GKGesture: Int {
    case Push = 0, Left, Right, Up, Down
}

在 iPhone 上接收消息:

func session(session: WCSession, didReceiveMessage message: [String : AnyObject]) {

        //retrieve info
        let type = message["Type"] as! String
        let content = message["Content"]

        switch type {

        case "Gesture":
            handleGesture(GKGesture(rawValue: content as! Int)!)
        default:
            print("Received message \(message) is invalid with type of \(type)")
        }

    }

    func handleGesture(gesture : GKGesture){

        print("iPhone receives gesture \(gesture)")

        var notificationName = ""

        switch gesture {

        case .Up:
            notificationName = "GestureUp"
        case .Down:
            notificationName = "GestureDown"
        case .Left:
            notificationName = "GestureLeft"
        case .Right:
            notificationName = "GestureRight"
        case .Push:
            notificationName = "GesturePush"
        }

        NSNotificationCenter.defaultCenter().postNotificationName(notificationName, object: nil)

    }

不知何故,我无法在 Xcode 上调试我的 Watch 应用程序,调试会话不会附加。我不知道为什么。因此,我只用 iPhone 进行单面调试。

有时我会打印出“接收手势”,有时不会。获取通知也是如此。

4

3 回答 3

6

我不知道 Int 在 WCSession 中传输时是否会被包裹到 NSNumber。如果是这样,那么这就是为什么当我使用 Int 作为枚举的基类时它不起作用并且当 String 是基类时起作用。

连接性已知问题 将 NSNumber 和 NSDate 对象与 WCSession API 一起使用时,您的应用程序可能会崩溃。

解决方法:在调用 WCSession API 之前将 NSNumber 或 NSDate 对象转换为字符串。在接收端进行相反的转换。

观看 OS 2 Beta 4 发行说明

于 2015-08-17T22:15:51.293 回答
2

我的猜测是您对 sendMessage 的调用在失败的情况下返回错误,但您还没有实现错误处理程序!现在,当你启动并运行时,你可以只打印错误,但如果这是运输代码,你真的应该处理适当的错误:

//  send message
session.sendMessage(message, replyHandler: nil, errorHandler: { (error) -> Void in
    print("Watch send gesture \(gesture) failed with error \(error)")
})
print("Watch send gesture \(gesture)")
于 2015-07-08T15:38:25.870 回答
1

您的流程是正确的,但困难在于了解如何调试:

调试观察:

  1. 运行 iPhone 目标,完成后点击停止按钮。
  2. 在模拟器中打开 iOS 应用程序(从模拟器中手动运行,而不是从 Xcode 中运行)并让它挂在那里。
  3. 切换到 Watch 目标(yourAppName WatchKit App),放置相关断点并运行。
  4. iOS 应用程序将自动置于后台,然后您将能够使用 sendMessage 方法(在 Watch 目标处)发送您需要的任何内容,如果您的 iOS 应用程序中有 replayHandler,您甚至会在在 Watch 目标(即 InterfaceController)处发送消息

小斯威夫特示例:

将字典从Watch发送到 iOS 应用程序:

    if WCSession.defaultSession().reachable == true {
        let requestValues = ["Send" : "From iWatch to iPhone"]
        let session = WCSession.defaultSession()

        session.sendMessage(requestValues,
            replyHandler: { (replayDic: [String : AnyObject]) -> Void in
                print(replayDic["Send"])

            }, errorHandler: { (error: NSError) -> Void in
                print(error.description)
        })
    }
    else
    {
        print("WCSession isn't reachable from iWatch to iPhone")
    }

从 Watch 接收消息并从iOS应用发送重播:

    func session(session: WCSession, didReceiveMessage message: [String : AnyObject], replyHandler: ([String : AnyObject]) -> Void) {

      print(message.values)

      var replyValues = Dictionary<String, AnyObject>()

      replyValues["Send"] = "Received from iphone"
      // Using the block to send back a message to the Watch
      replyHandler(replyValues)
     }

调试 iPhone:

与调试手表完全相反

此外,@sharpBaga 的回答有一个重要的考虑因素。

于 2016-01-21T09:46:00.643 回答