0

I started messing around with the Watch OS framework today and wanted to throw together a quick app, but have come to a couple questions.

I made an iOS app that just shows the current battery % as well as the state of the battery. I then wanted to show that over on the watch.

  1. The only time the watch app will update is when I totally close the iOS app, then open it, while the watch app is active. How do I allow my watch app to be updated if I open it after the iOS app has been opened?

  2. This kind of goes with number 2. But how do I allow the watch app to fetch info from the iOS app, after it has been in the background? As an example, lets say the iOS app has been in the background and I wanted to fetch the battery % without opening the iOS app to the foreground.

Some side notes on how I set this up -

Within the iOS app, in the viewDidLoad method, I start my session.

 if ([WCSession isSupported]) {
    wcSession = [WCSession defaultSession];
    wcSession.delegate = self;
    [wcSession activateSession];
}

Then call my method to update the actual battery % and state. Within that method, I have this which sends the info over to the watch:

NSDictionary *message = @{
                          @"message" : [NSString stringWithFormat:@"%@", [numberFormatter stringFromNumber:levelObj]],
                          @"message_2" : [NSString stringWithFormat:@"%ld",(long)[UIDevice currentDevice].batteryState],

                          };


[wcSession sendMessage:message replyHandler:nil errorHandler:^(NSError * _Nonnull error) {
    NSLog(@"%@", error.localizedDescription);
}];

I also call this same method in the viewDidAppear, so I don't have to relaunch the app completely, to allow refreshing of the watch counterpart.

On the watch side I have the viewWillActivate method with the same activation as the iOS side as well as the method to handle what the watch app receives from the iOS side. But it will only update when I restart the iOS app fully.

    - (void)session:(WCSession *)session didReceiveMessage:(NSDictionary<NSString *,id> *)message {

    NSLog(@"Message recieved!");
    [_batteryLevelLabelW setText:message[@"message"]];
}

Also in there is the code to handle the battery state message, which is a bit long.

I hope I gave a good amount of information to help.

Michael
  • 193
  • 2
  • 12

1 Answers1

0

According to documentation:

Use the send​Message(_:​reply​Handler:​error​Handler:​) or send​Message​Data(_:​reply​Handler:​error​Handler:​) method to transfer data to a reachable counterpart. These methods are intended for immediate communication between your iOS app and WatchKit extension. The is​Reachable property must currently be true for these methods to succeed.

If watchapp is not foreground, message will not be delivered since isReachable is false.

Method you should use is update​Application​Context(_:​) - it will wait till watch app will be opened at foreground and only then will be delivered.

abjurato
  • 1,439
  • 11
  • 17
  • Thank you for your response. What if thew iOS app has not been opened yet. How would that be refreshed, then sent to the watch app when `isReachable` is true. – Michael Apr 02 '17 at 18:52
  • @Michael if ios app has not been opened yet, how are you going to get battery level? – abjurato Apr 02 '17 at 18:54
  • That's my bad. Should have rephrased that differently. Is there a way to refresh that battery level if the watch app sends it a message asking for the info? Or would I definitely have to open the iOS one first? – Michael Apr 02 '17 at 19:09
  • @Michael you can send instant message from watch to phone via `sendMessage(_:replyHandler:errorHandler:)` - in this direction only valid session is needed and `isReachable` is not necessary. And respond with battery level. Sending message from phone to watch needs watch app to be foreground, sending message from watch app to ios app allows ios app to be background/suspended. But anyway ios app should be launched to activate WCSession. – abjurato Apr 02 '17 at 19:28
  • Ah, understood. Thank you. – Michael Apr 02 '17 at 19:30