WCSession.sendMessage works 50/50

假如想象 提交于 2019-11-29 09:44:35

I don't know if Int would be wrapped around to NSNumber while being transfer within WCSession. If it would be, then that must be why when I use Int as the base class of the enum it won't work and works when String is the base class.

Connectivity Known Issue Your app may crash when using NSNumber and NSDate objects with the WCSession API.

Workaround: Convert an NSNumber or NSDate object to a string before calling WCSession APIs. Do the opposite conversion on the receiving side.

Watch OS 2 Beta 4 release note

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

Your flow is correct but the difficulty is to understand how to debug:

Debug Watch:

  1. Run the iPhone target and when it is done hit the Stop button.
  2. Open the iOS app inside the simulator (run it manually from the simulator and not from Xcode) and let it hang there.
  3. Switch to the Watch target (yourAppName WatchKit App), put the relevant breakpoint and run it.
  4. The iOS app will be put automatically in the background and then you will be able to use sendMessage method (at the Watch target) to send whatever you need and if you have a replayHandler in your iOS app you will even receive the relevant messages inside the sendMessage at your Watch target (i.e InterfaceController)

Small Swift example:

Sending a Dictionary from Watch to iOS app:

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

Receiving the message from the Watch and sending a replay from the iOS app:

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

Debug iPhone:

The exact opposite of debug watch

Also, the answer by @sharpBaga has an important consideration.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!