WCSession.метод SendMessage работает 50/50

в последнее время я работаю над проектом, связанным с communication Watch/iPhone communication снова. Но мой код иногда работает и иногда не работает, что для меня странно, потому что я думаю, что код должен работать или нет. Он не может быть 50/50. Поэтому я понятия не имею, что происходит.

настройка WCSession на iPhone:

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

    ... ...
}

похожие 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")
        }
    }

    ... ...
}

отправить сообщение на Смотреть:

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)

    }

как-то я не могу отладить свое приложение Watch Watch на Xcode, сеанс отладки просто не будет прикрепляться. Не знаю почему. Поэтому я отлаживаю односторонний только с iPhone.

иногда я получаю распечатку" получает жест", а иногда нет. И то же самое для получение уведомления.

3 ответов


Я не знаю, будет ли Int обернут вокруг NSNumber при передаче в WCSession. Если это так, то именно поэтому, когда я использую Int в качестве базового класса перечисления, он не будет работать и работает, когда String является базовым классом.

подключение известная проблема ваше приложение может произойти сбой при использовании NSNumber и Объекты NSDate с API WCSession.

обходной путь: преобразование объекта NSNumber или NSDate в строку перед вызов API WCSession. Делать обратное преобразование на приемном сторона.

смотреть OS 2 Beta 4 примечание к выпуску


Я предполагаю, что ваш вызов 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)")

ваш поток верен, но сложность заключается в том, чтобы понять, как отлаживать:

Отладки:

  1. выполнить цели iPhone и когда это будет сделано, нажмите кнопку "Стоп".
  2. Откройте приложение iOS внутри симулятора (запустите его вручную из симулятора, а не из Xcode) и пусть он висит там.
  3. переключитесь на цель Watch (приложение Yourappname WatchKit), поместите соответствующую точку останова и запустите ее.
  4. приложение iOS будет поместите автоматически в фоновом режиме, а затем вы сможете использовать метод sendMessage (в цели Watch), чтобы отправить все, что вам нужно, и если у вас есть replayHandler в вашем приложении iOS, вы даже получите соответствующие сообщения внутри sendMessage в вашей цели Watch (i.E InterfaceController)

маленький пример Swift:

отправка словаря из посмотреть для приложения 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")
    }

получение сообщения от Смотреть и отправлять повтор из 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)
     }

отладка iPhone:

полная противоположность debug watch

кроме того, ответ @sharpBaga имеет важное значение.