Recently I was working with watchOS 3 and iOS – transferring data back and forth (not using reply callbacks). I was using .sendMessage, and messages from the iPhone to the watch were very quick. However, messages from the watch to the phone seemed very slow, or so I thought.
This is what my receive delegate looked like on the iPhone side of the BLE fence.
// Message received from the Apple Watch Extension. func session(_ session: WCSession, didReceiveMessage message: [String : Any]) { let val = message["ancValue"] as! String messageFromWatchLabel.text = "ANC: \(val)" }
That took anywhere from 1 to 25 seconds to populate the UILabel. Now, I miraculously remembered reading somewhere that on the iPhone, the delegate call comes back on a background thread. My eyes lit up, and I tried updating my UI on the main thread (where it needs to happen).
// Message received from the Apple Watch Extension. func session(_ session: WCSession, didReceiveMessage message: [String : Any]) { let val = message["ancValue"] as! String // Main thread - super snappy. DispatchQueue.main.async { self.messageFromWatchLabel.text = "ANC: \(val)" self.slider.value = Float(val)! self.sliderValue.text = "\(Int(val)!)" } }
Shazaam. Snappy as can be. So try not to forget about this. I didn’t need to do this on the watch side because I assume there is no threading on the watch (that we have access to)? It’s very snappy in response to the same delegate on the watch side, so I’m not sure what’s going on there. But that main thread for iOS saved my bacon.