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
WCSession
delegate and takes care of persisting the information, and then notifying the relevant parties (view controllers, etc) that the backing data has been updated.