How to get Apple Watch to update pages created with WKInterfaceController reloadRootControllersWithNames: contexts?

634 views Asked by At

I have a WKInterfaceController for a watchkit app, InterfaceController.m. It creates paginated content like this:

- (void)willActivate {
    [super willActivate];
    NSDate *now = [[NSDate alloc] init];
    NSDictionary *time = @{@"time":[NSString stringWithFormat:@"%f",[now timeIntervalSince1970]]};
    NSArray *contexts = [[NSArray alloc] initWithObjects:time,time,nil];
    NSArray *names = [[NSArray alloc] initWithObjects:@"page",@"page",nil];
    [WKInterfaceController reloadRootControllersWithNames:names contexts:contexts];
}

The WKInterfaceController with "page" as the identifier is called PageInterfaceController.m and just displays the time sent by InterfaceController.m

- (void)awakeWithContext:(id)context {
    [super awakeWithContext:context];
    [label setText:[context objectForKey:@"time"]];
}

This works great the first time it's loaded, but after exiting and relaunching the app, it shows the old times. How can I get the app to go back to InterfaceController.m and update the times?

Yes, I know I could just put the time in PageInterfaceController, but in my real app, the InterfaceController is getting location data and sending it to the pages, even determining the number of pages to be created.

You can download the whole sample project here:

https://github.com/tomkincaid/WatchInterfaceTest

2

There are 2 answers

3
John Stephen On

awakeWithContext will not be called a second time if the watch keeps the controller loaded, which is probably why it doesn't get updated after the initial load.

Instead, use viewWillActivate in your PageInterfaceController just like you do in your main InterfaceController, like this:

- (void)viewWillActivate {
    [super viewWillActivate];
    [label setText:[context objectForKey:@"time"]];
}
0
Tom Kincaid On

Workaround is to use a timer and make it go back to the first interface controller after a certain time. Not ideal as I wish there was a way to have it start from the first interface controller every time the watch app is launched.

- (void)awakeWithContext:(id)context {
    [super awakeWithContext:context];
    time = [context objectForKey:@"time"];
}

- (void)willActivate {
    [super willActivate];
    NSDate *now = [[NSDate alloc] init];
    double diff = [now timeIntervalSince1970] - [time doubleValue];
    if (diff > 30) {
        NSArray *contexts = [[NSArray alloc] initWithObjects:@"",nil];
        NSArray *names = [[NSArray alloc] initWithObjects:@"main",nil];
        [WKInterfaceController reloadRootControllersWithNames:names contexts:contexts];
    } else {
        [label setText:[NSString stringWithFormat:@"%@",time]];
    }