I am using WatchConnectivity framework to receive a string from my app. Here is how I send the string in Obj-C from the app:
-(void) viewDidLoad {
//WATCHKIT
WCSession* session = [WCSession defaultSession];
session.delegate = self;
[session activateSession];
[self sendInfoToWatch];
}
-(void) sendInfoToWatch {
WCSession* session = [WCSession defaultSession];
session.delegate = self;
[session activateSession];
[session sendMessage:@{@"a":@"hello"} replyHandler:^(NSDictionary<NSString *,id> * _Nonnull replyMessage) {
} errorHandler:^(NSError * _Nonnull error) {
}];
}
My Watch app is in Swift. This is how I retrieve the message:
Note: "wc session is supported" works and gets logged to the console
override func willActivate() {
if(WCSession.isSupported()){
NSLog("wc session is supported")
self.session = WCSession.defaultSession()
self.session.delegate = self
self.session.activateSession()
}
super.willActivate()
}
The following function is never called, none of the NSLog's show up, so the QRCodeTitleLabel does not update its text.
func session(session: WCSession, didReceiveMessage message: [String : AnyObject]) {
//recieving message from iphone
QRCodeTitleLabel.setText(message["a"]! as? String)
NSLog("This was called")
NSLog((message["a"]! as? String)!)
}
Does anyone know why this method is not called?
Also, I have imported WatchConnectivity and included WCSessionDelegate after my class name.
Edit:
I added the function with replyHandler, but this method still isn't called:
func session(session: WCSession, didReceiveMessage message: [String : AnyObject], replyHandler: ([String : AnyObject]) -> Void) {
QRCodeTitleLabel.setText(message["a"]! as? String)
NSLog("This was called")
NSLog((message["a"]! as? String)!)
}
There are 2 session:didReceiveMessage methods in the WCSession. You should implement the one with a replyHandler on the Apple Watch side.
Also, is the Apple Watch screen on? SendMessage from the iPhone will only work while the Apple Watch app is active and the screen is on. SendMessage from the Apple Watch to the iPhone on the other hand will work even if the iPhone app is not launched.
If you want to request the data when using the Watch app, you could switch the Watch App to call the sendMessage method. The iPhone app would use its replyHandler to send the data you need back to the watch. If you do this, you will need to move your WCSession initialization code in the iPhone app into the application:didFinishLaunchingWithOptions method (since your view controller will not be initialized if launched in the background).
// ***On the watch***
// ExtensionDelegate
func applicationDidFinishLaunching() {
self.session = WCSession.defaultSession();
self.session.delegate = self
self.session.activateSession()
}
// Where you want to get the data from the iPhone
self.session.sendMessage(["retrieveData":[:]], replyHandler: { (result) -> Void in
// TODO: Handle your data from the iPhone
}, errorHandler: { (error) -> Void in
// TODO: Handle error - iPhone many not be reachable
})
// ***On the iPhone***
// AppDelegate
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
self.session = [WCSession defaultSession];
self.session.delegate = self;
[self.session activateSession];
}
- (void)session:(WCSession *)session didReceiveMessage:(nonnull NSDictionary<NSString *,id> *)message replyHandler:(nonnull void (^)(NSDictionary<NSString *,id> * _Nonnull))replyHandler
{
if ([message objectForKey:@"retrieveData"])
{
replyHandler(@{@"a":@"hello"});
}
}