What is the proper way to handle communication sent and received from multiple controllers?
What I'm trying to do is send a message from two different viewControllers from iOS to two different interfaceControllers in WatchOS (separately, NOT at the sametime).
Here is what I have which only works for communication between ViewController2 and InterfaceController2, it crashes when a messages is sent from ViewController1 to InterfaceController1 since it appears to be targeting the session method from InterfaceController2 all the time.
ViewController 1:
class ViewController1: UIViewController,WCSessionDelegate{
    var session: WCSession!
    override func viewDidLoad() {
      super.viewDidLoad()
        if WCSession.isSupported() {
          session = WCSession.default()
          session.delegate = self
          session.activate()
        }
     }
      func sendDataToWatch(){
        let sendPrice:[String: Double] = ["price": 3.99]
        session.sendMessage(sendPrice, replyHandler: { replyMessage in
            // Some reply here, this could be nil
        }, errorHandler: {error in
            // Catch any errors here, this could be nil
            print("Error: \(error.localizedDescription)")
        })
     }
}
InterfaceController 1: Receives message form ViewController 1
class InterfaceController1: WKInterfaceController, WCSessionDelegate{
   var session: WCSession!
    override func awake(withContext context: Any?) {
        super.awake(withContext: context)
        if (WCSession.isSupported()) {
            session = WCSession.default()
            session.delegate = self
            session.activate()
        }
    }
   func session(_ session: WCSession, didReceiveMessage message: [String : Any], replyHandler: @escaping ([String : Any]) -> Void) {
    /// Capture data from ViewContorller 2
    let priceFromPhone = message["price"] as? String
    // do something with priceFromPhone
   } 
}
// ===========================================
ViewController 2:
class ViewController2: UIViewController,WCSessionDelegate{
    var session: WCSession!
    override func viewDidLoad() {
      super.viewDidLoad()
        if WCSession.isSupported() {
          session = WCSession.default()
          session.delegate = self
          session.activate()
        }
     }
   func sendDataToWatch(){
    let sendEngine:[String: Double] = ["engine": 2.5]
    session.sendMessage(sendEngine, replyHandler: { replyMessage in
        // Some reply here, this could be nil
    }, errorHandler: {error in
        // Catch any errors here, this could be nil
        print("Error: \(error.localizedDescription)")
    })
  }
}
InterfaceController 2: Receives message from ViewController 2
class InterfaceController2: WKInterfaceController, WCSessionDelegate{
   var session: WCSession!
    override func awake(withContext context: Any?) {
        super.awake(withContext: context)
        if (WCSession.isSupported()) {
            session = WCSession.default()
            session.delegate = self
            session.activate()
        }
    }
   func session(_ session: WCSession, didReceiveMessage message: [String : Any], replyHandler: @escaping ([String : Any]) -> Void) {
      /// Capture data from ViewContorller 2
      let engineFromPhone = message["engine"] as? String
      // do something with engineFromPhone
    }    
 }
Thanks
 
                        
I'd suggest removing all data management away from the controllers that handle your UI. It is a poor design and will likely cause you headaches later to mix the layers like this.
You should instead have a data manager that is the
WCSessiondelegate and takes care of persisting the information, and then notifying the relevant parties (view controllers, etc) that the backing data has been updated.