Launch Watch App into Middle View

Launch Watch App into middle view

WKInterfaceController's becomeCurrentPage() should be what you're looking for.

Let's create a new class for the center view controller, CenterPageViewController, and change its initWithContext: method as follows

import WatchKit

class CenterPageViewController: WKInterfaceController {

override init(context: AnyObject?) {
super.init(context: context)

super.becomeCurrentPage()
}
}

Now let's set the Custom Class for the middle page in your storyboard to CenterPageViewController

Sample Image

and finally hit run.

You won't be able to get rid of the initial transition from the left page to the center page, but the app will finally begin on the middle page.

Load second app interface in a segue

Building my first Apple Watch app over here :)

Looks like there is a concept of UINavigationController-ish behaviour built into the WKInterfacesController.

Take a look at: pushControllerWithName(_:context:)

And from some docs I found here:

Hierarchical. This style is suited for apps with more complex data models or apps whose data is more hierarchical. A hierarchical interface always starts with a single root interface controller. In that interface controller, you provide controls that, when tapped, push new interface controllers onto the screen.

EDIT:
Looking into this some more. WatchKit is currently very limited by the looks.

The best solutions I could come up with was to add the three InterfaceController, with segues is between. Left -> Main -> Right.

Sample Image

Then assign a custom SKInterfaceController for Main:

class InterfaceController: WKInterfaceController {  
override init() {
super.init()
becomeCurrentPage()
}
}

This creates an annoying animation in the beginning where you will see "Left" on start and how "Main" is animated pushed in. I don't see any better way to do this at this early stage of WatchKit.

How to segue to the middle InterfaceController in Page Based Navigation on Apple Watch?

Not sure if it's possible to do it in the storyboard as I was attempting, but figured out how to do exactly what I wanted via code:

    WKInterfaceController.reloadRootPageControllers(withNames: ["testIC1", "testIC2", "testIC3"],
contexts: [contextDictionary],
orientation: .horizontal,
pageIndex: 1)
}

Using WCSession with more than one ViewController

As far as I understand the task you just need synchronisation in a Phone -> Watch direction so in a nutshell a minimum configuration for you:

Phone:

I believe the application:didFinishLaunchingWithOptions: handler is the best place for the WCSession initialisation therefore place the following code there:

if ([WCSession isSupported]) {
// You even don't need to set a delegate because you don't need to receive messages from Watch.
// Everything that you need is just activate a session.
[[WCSession defaultSession] activateSession];
}

Then somewhere in your code that measures a heart rate for example:

NSError *updateContextError;
BOOL isContextUpdated = [[WCSession defaultSession] updateApplicationContext:@{@"heartRate": @"90"} error:&updateContextError]

if (!isContextUpdated) {
NSLog(@"Update failed with error: %@", updateContextError);
}

update:

Watch:

ExtensionDelegate.h:

@import WatchConnectivity;
#import <WatchKit/WatchKit.h>

@interface ExtensionDelegate : NSObject <WKExtensionDelegate, WCSessionDelegate>
@end

ExtensionDelegate.m:

#import "ExtensionDelegate.h"

@implementation ExtensionDelegate

- (void)applicationDidFinishLaunching {
// Session objects are always available on Apple Watch thus there is no use in calling +WCSession.isSupported method.
[WCSession defaultSession].delegate = self;
[[WCSession defaultSession] activateSession];
}

- (void)session:(nonnull WCSession *)session didReceiveApplicationContext:(nonnull NSDictionary<NSString *,id> *)applicationContext {
NSString *heartRate = [applicationContext objectForKey:@"heartRate"];

// Compose a userInfo to pass it using postNotificationName method.
NSDictionary *userInfo = [NSDictionary dictionaryWithObject:heartRate forKey:@"heartRate"];

// Broadcast data outside.
[[NSNotificationCenter defaultCenter] postNotificationName: @"heartRateDidUpdate" object:nil userInfo:userInfo];
}

@end

Somewhere in your Controller, let's name it XYZController1.

XYZController1:

#import "XYZController1.h"

@implementation XYZController1

- (void)awakeWithContext:(id)context {
[super awakeWithContext:context];

[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(handleUpdatedHeartRate:) name:@"heartRateDidUpdate" object:nil];
}

-(void)handleUpdatedHeartRate:(NSNotification *)notification {
NSDictionary* userInfo = notification.userInfo;
NSString* heartRate = userInfo[@"heartRate"];
NSLog (@"Successfully received heartRate notification!");
}

@end

Code hasn't been tested I just wrote it as is so there can be some typos.

I think the main idea now is quite clear and a transfer of remaining types of data is not that tough task.

My current WatchConnectivity architecture much more complicated but nevertheless it is based on this logic.

If you still have any questions we might move a further discussion to the chat.



Related Topics



Leave a reply



Submit