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. Делать обратное преобразование на приемном сторона.
Я предполагаю, что ваш вызов 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)")
ваш поток верен, но сложность заключается в том, чтобы понять, как отлаживать:
Отладки:
- выполнить цели iPhone и когда это будет сделано, нажмите кнопку "Стоп".
- Откройте приложение iOS внутри симулятора (запустите его вручную из симулятора, а не из Xcode) и пусть он висит там.
- переключитесь на цель Watch (приложение Yourappname WatchKit), поместите соответствующую точку останова и запустите ее.
- приложение 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 имеет важное значение.