WCSession.sendMessage工作50/50

时间:2015-07-08 03:04:21

标签: ios swift watch-os-2

最近,我正在研究一个与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调试片面。

有时我得到了#34;接收手势“打印出来,有时候没有。获取通知也一样。

3 个答案:

答案 0 :(得分:6)

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

  

连接已知问题使用NSNumber时,您的应用可能会崩溃   使用WCSession API的NSDate对象。

     

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

Watch OS 2 Beta 4 release note

答案 1 :(得分:2)

My guess is your call to sendMessage is returning an error in the cases where it fails, but you haven't implemented the error handler!! For now while you are getting up and running you can get away with just printing the error, but if this is shipping code you really ought to handle the appropriate errors:

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

答案 2 :(得分:1)

您的流量是正确的,但难以理解如何调试:

调试观察:

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

    观看发送字典到iOS应用:

    process.on("unhandledRejection", () => process.exit(1)); 
    

    接收来自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")
        }
    

    调试iPhone:

    与调试手表完全相反

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