2016-02-02 22 views
6

Ich verwende Watch Connectivity, um ein Array vom iPhone zur Watch anzufordern.Fehler: "Nachrichtenantwort hat zu lange gedauert" - WCSession Watch OS2

Die Idee war zu sendMessage von der Uhr, und das iPhone wird mit dem Array innerhalb der didReceiveMessage Methode antworten.

Allerdings scheint das iPhone nicht zu reagieren, ich dachte, das iPhone würde die Anwendung öffnen, wenn ich die Nachricht von der Uhr senden. Ich habe sogar versucht, die Anwendung zu öffnen, als ich sendMessage aber immer noch kein Glück. Wenn ich lange genug warte, erhalte ich die folgende Fehlermeldung:

Wer weiß, wo ich vielleicht falsch liege?

Apple Watch

import WatchKit 
import Foundation 
import CoreData 
import WatchConnectivity 

class BookmarkedInterfaceController: WKInterfaceController, WCSessionDelegate { 

var session : WCSession! 
var objects: [AnyObject]! 

@IBOutlet var table: WKInterfaceTable! 

override func willActivate() { 
    super.willActivate() 
    //Check if session is supported and Activate 
    if (WCSession.isSupported()) { 
     session = WCSession.defaultSession() 
     session.delegate = self 
     session.activateSession() 
    } 
    sendMessageToIphone() 
} 
func sendMessageToIphone() { 
    if WCSession.defaultSession().reachable { 

     print("WCSession is reachabe") 

     let messageDict = ["Request": "iPhone Can You Give Me The Array"] 
     WCSession.defaultSession().sendMessage(messageDict, replyHandler: { (replyDict) -> Void in 
      print(replyDict) 
      }, errorHandler: { (error) -> Void in 
       print(error) 
     }) 
    } 
} 

func session(session: WCSession, didReceiveMessage message: [String : AnyObject]) { 
    //recieving message from iphone 
    print("recieved message from iphone \(message)") 

    objects.append(message["Array"]!) 

    print("Objects array = \(objects)")   
} 

Die Konsole Ausgänge

WCSession is reachabe Array nil

iPhone App Delegierter

import UIKit 
import CoreData 
import WatchConnectivity 

@UIApplicationMain 

class AppDelegate: UIResponder, UIApplicationDelegate, WCSessionDelegate { 

var window: UIWindow? 
var session : WCSession! 

func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool { 

    //Check if session is supported and Activate 
    if (WCSession.isSupported()) { 
     session = WCSession.defaultSession() 
     session.delegate = self 
     session.activateSession() 
    } 
} 

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

    print("did recieve message from Watch") 

    let applicationData = ["Array":["One", "Two", "Three"]] 

    replyHandler(applicationData) 

} 

Nichts von dem iPhone ausgeführt wird. Auch wenn ich die App manuell öffne.

+0

Ihr Code sieht gut aus für mich. Nur eine Frage, Sie verwenden die gleichen Dummy-Daten ('[" Array ": [" One "," Two "," Three "]]'), oder? Denn wenn Sie einen anderen Code-Block ausführen lassen, um die eigentlichen Daten zurückzusenden, könnte es ein anderes Problem geben. Z.B. Ein Array von benutzerdefinierten Objekten kann nicht wie folgt an Watch App zurückgegeben werden. – Gandalf

+0

@Gandalf Ich wollte zuerst mit einem Array von Strings üben, das innerhalb der WCSession-Funktionen gesendet und ausgedruckt wurde. Mein Ziel war es, ein Array von NSManagedObjects an die Watch zu senden, um sie in der Tabelle anzuzeigen. Im Grunde würde der Antworthandler auf dem Telefon das Wörterbuch mit einem Array von Objekten an die Uhr senden. Wirklich komisch, wie ich das Telefon nicht beantworten kann:/Xcode mit der neuen Version aktualisieren und hoffen auf die beste – RileyDev

Antwort

3

Wenn Sie die Antwort auf die Nachricht die Uhr wollen die angeforderten Daten enthalten gesendet, sollten Sie Ihren Code wie folgt ändern:

Uhr

func sendMessageToIphone() { 
    if WCSession.defaultSession().reachable { 

     print("WCSession is reachabe") 

     let messageDict = ["Request": "iPhone Can You Give Me The Array"] 
     WCSession.defaultSession().sendMessage(messageDict, replyHandler: { (replyDict) -> Void in 
      print("Array \(replyDict["array"])") 
      }, errorHandler: { (error) -> Void in 
       print(error) 
     }) 
    } 
} 

Telefon

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

    print("did recieve message from Watch") 

    let applicationData = ["Array":["One", "Two", "Three"]] 

    //If identifier from recievedMessage is for Objects 

    replyHandler(applicationData) 

} 

Und der Grund, warum die sendMessage vom Telefon nicht von der Uhr empfangen wird, liegt darin, dass Sie die falsche Delegate-Methode für den von Ihnen verwendeten sendMessage-Aufruf implementiert haben.

Wenn Sie nachrichts mit einem nil replyHandler dann dieser Delegat-Methode aufrufen, wird auf der Empfangsseite aufgerufen werden: func session(session: WCSession, didReceiveMessage message: [String : AnyObject])

Wenn Sie nachrichts mit einem Nicht-Null replyHandler dann dieser Delegat-Methode aufrufen wird Auf der Empfangsseite aufgerufen: func session(session: WCSession, didReceiveMessage message: [String : AnyObject], replyHandler: ([String : AnyObject]) -> Void)

+0

Vielen Dank für Ihre Antwort, also habe ich den Code zu dem, was Sie vorgeschlagen, leider bin ich mir nicht sicher, was Sie über die sagen Empfangen der Nachricht auf der Uhr vom iPhone. Willst du sagen, ich sollte 'func session' ändern (Sitzung: WCSession, didReceiveMessage Nachricht: [String: AnyObject]) {print ("erhaltene Nachricht von iphone \ (Nachricht)"}}? Auch bei den aktuellen Updates bekomme ich die folgende Ausgabe in der Konsole: .WCSession ist erreichbar Array nil Programm beendet mit Exit Code: 0' – RileyDev

+0

komisch; vielleicht versuche 'print ("Array \ (replyDict [" array "])") zu 'printen (" replyDict \ (replyDict) ")' – ccjensen

0

Sie müssen die Sitzung aktivieren, bevor Sie die Nachricht senden. Außerdem müssen Sie den Delegaten festlegen, bevor Sie die Sitzung aktivieren, da Sie einige ausstehende Nachrichten verlieren können.

iphone Seite:

import UIKit 
import WatchConnectivity 

@UIApplicationMain 
class AppDelegate: UIResponder, UIApplicationDelegate, WCSessionDelegate { 

var window: UIWindow? 
var session : WCSession! 

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

    print("did recieve message from Watch") 
    let applicationData = ["Array":["One", "Two", "Three"]] 

    //If identifier from recievedMessage is for Objects 
    session.sendMessage(applicationData, replyHandler: { reply in 
     print("Got reply: \(reply)") 
     }, errorHandler: { error in 
      print("error: \(error)") 
    }) 
} 

func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool { 
    session = WCSession.defaultSession() 
    session.delegate = self 
    session.activateSession() 
    return true 
} 
} 

iWatch Erweiterung InterfaceController Sie müssen die Sitzung in der Interface-Controller willactivate Methode aktivieren.

import WatchKit 
import Foundation 
import WatchConnectivity 

class InterfaceController: WKInterfaceController, WCSessionDelegate { 

var session : WCSession! 
var objects: [AnyObject]! 

override func awakeWithContext(context: AnyObject?) { 
    super.awakeWithContext(context) 

    // Configure interface objects here. 
} 
override func willActivate() { 
    // This method is called when watch view controller is about to be visible to user 
    super.willActivate() 
    session = WCSession.defaultSession() 
    session.delegate = self 
    session.activateSession() 
    objects = [] 
    sendMessageToIphone() 
} 

override func didDeactivate() { 
    // This method is called when watch view controller is no longer visible 
    super.didDeactivate() 
} 

func sendMessageToIphone() { 
    if WCSession.defaultSession().reachable{ 

     print("WCSession is reachabe") 

     let messageDict = ["Request": "iPhone Can You Give Me The Array"] 
     WCSession.defaultSession().sendMessage(messageDict, replyHandler: { (replyDict) -> Void in 
      print(replyDict) 
      }, errorHandler: { (error) -> Void in 
       print(error) 
     }) 
    } 
} 

func session(session: WCSession, didReceiveMessage message: [String : AnyObject]) { 
    //recieving message from iphone 
    print("recieved message from iphone \(message)") 

    objects.append(message["Array"]!) 

    print("Objects array = \(objects)") 
} 
} 

Hinweis. Führen Sie zuerst die iPhone-Anwendung aus. Führen Sie dann die Erweiterung aus und halten Sie die iPhone App im Vordergrund.

+0

Sorry, ich habe meine Frage mit dem vollen Code aktualisiert, ich hatte bereits die aktiviert Sitzung und setzen Sie den Delegierten. – RileyDev

+0

@JKSDEV Auf der Watch-Seite: Sie haben das Objekt-Array nicht initialisiert. Bitte lege leere Array-Objekte = [] in der Methode willActivate an. –