Send and receive messages from iPhone to Watch from multiple Controllers

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

Replies

There's only on WCSession object on the iOS side, and one on the watchOS side. Your code is changing the delegate of that object on each side. If the iOS side is on ViewController 1, its messages will get sent to either InterfaceController 1 or InterfaceController 2, depending on which one is currently the watchOS WCSession delegate.