Reputation: 470
I'm sending a message from iPhone to Watch (WatchOS2) where there is an internal timer runs on the iPhone. For every 30 seconds, I'm sending the message from the iPhone to watch. Unfortunately, send message is working only for the first time, where my watch is receiving successfully. But, from the next time watch is not receiving any message. The whole scenario works perfectly in the simulator but not on the actual watch. Any help would be appreciated. I tried to send the message from the main thread but of no use. Any idea on where I'm doing wrong.
Thanks in advance.
this is the code I use
At watch side
//InterfaceController1.m
- (void)willActivate {
// This method is called when watch view controller is about to be visible to user
[super willActivate];
if ([WCSession isSupported]) {
self.session = [WCSession defaultSession];
self.session.delegate = self;
[self.session activateSession];
[self.session sendMessage:@{@"OpeniOS":@"YES"} replyHandler:nil errorHandler:nil];
}
}
- (void)session:(WCSession *)session didReceiveMessage:(NSDictionary<NSString *, id> *)message replyHandler:(void(^)(NSDictionary<NSString *, id> *replyMessage))replyHandler{
//able to receive message - dictionary with IssuerNames Array from iPhone
[self setupTable:message]//I'm setting up my tableview and on click of a row from tableview I'm pushing the user to InterfaceController2.m
}
- (void)table:(WKInterfaceTable *)table didSelectRowAtIndex:(NSInteger)rowIndex{
[self.session sendMessage:@{@"AccSel":@"YES"} replyHandler:nil errorHandler:nil];
[self pushControllerWithName:@"InterfaceController2" context:[NSNumber numberWithInteger:rowIndex]];
}
//InterfaceController2.m
- (void)willActivate {
[super willActivate];
if ([WCSession isSupported]) {
_session = [WCSession defaultSession];
_session.delegate = self;
[_session activateSession];
}
}
-(void)session:(WCSession *)session didReceiveMessage:(NSDictionary<NSString *,id> *)message replyHandler:(void(^)(NSDictionary<NSString *, id> *replyMessage))replyHandler{
NSLog(@"%@",message);
}
At iPhone side
//ViewController1.m
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view.
if ([WCSession isSupported]) {
_session=[WCSession defaultSession];
_session.delegate=self;
[_session activateSession];
[_session sendMessage:@{@"testKey":@"testVal"} replyHandler:nil errorHandler:nil];
}
}
-(void)session:(WCSession *)session didReceiveMessage:(NSDictionary<NSString *,id> *)message{
if ([[message objectForKey:@"OpeniOS"] isEqualToString:@"YES"]) {
NSMutableArray *tempIssuerArray=[[NSMutableArray alloc] init];
for (OTPToken *token in self.tokenManager.tokens) {
[tempIssuerArray addObject:token.issuer];
}
if ([_session isReachable]) {
NSDictionary *temp=@{@"IssuerNames":tempIssuerArray};
[_session sendMessage:temp replyHandler:nil errorHandler:nil];
}
}
if ([[message objectForKey:@"AccSel"] isEqualToString:@"YES"]) {
OTPToken *token = [self.tokenManager.tokens objectAtIndex:[[message objectForKey:@"selIndex"] intValue]];
DisplayTokenViewController *dtvc=[self.storyboard instantiateViewControllerWithIdentifier:@"DisplayToken"];
dtvc.token=token;
dtvc.tkm=self.tokenManager;
[self.navigationController pushViewController:dtvc animated:YES];
}
}
//ViewController2.m
-(void)viewDidLoad {
[super viewDidLoad];
mySession=[WCSession defaultSession];
mySession.delegate=self;
[mySession activateSession];
[self refresh]; //this refresh method is called every 30 seconds based on a property change value
}
- (void)refresh{
NSDictionary* dict=@{@"code":@"123",@"name":@"abc"};
[mySession sendMessage:dict replyHandler:nil errorHandler:nil];
}
Actually, on the watch side, InterfaceController1.m is shown to the user at first, on a button click from InterfaceController1.m, user redirects to InterfaceController2.m. At the same time, on iPhone end I'm pushing the ViewController2.m from ViewController1.m on receiving a message from watch.
Here, the refresh method is called for only one time and after every 30 seconds, ideally refresh method should be called but not in the actual device. But everything is working perfectly in the simulator
Upvotes: 0
Views: 906
Reputation: 4656
When you use the WCSession sendMessage API with a nil replyHandler like this:
[_session sendMessage:@{@"testKey":@"testVal"} replyHandler:nil errorHandler:nil];
you need to implement the following delegate method on the receiving side:
- (void)session:(WCSession *)session didReceiveMessage:(NSDictionary<NSString *, id> *)message {
//able to receive message - dictionary with IssuerNames Array from iPhone
[self setupTable:message]//I'm setting up my tableview and on click of a row from tableview I'm pushing the user to InterfaceController2.m
}
rather than session:didReceiveMessage:replyHandler:. So in your example above, it seems that InterfaceController1.m
on the watch side should not be able to receive the message like you say it does. I'm guessing that perhaps you just made a copy paste error as you were sanitizing the code for SO.
Upvotes: 1