Search code examples
watchkitinfo.plist

How does watchOS find the main storyboard file?


I would like to have two storyboard files for feature flag reasons. Only one will be used at a time, but I want to have two files for switching back and forth between builds. However, I cannot find where watchOS determines which storyboard file to load.

iOS has a key UIMainStoryboardFile in Info.plist. But watchOS has no such key.

When I check our current Watch Extension and Watch App targets in both the General and Info sections, I see no mention of storyboard files.

Note that watchOS does have WKExtensionDelegateClassName key for Info.plist, which will also serve my feature flag purpose. However, no code in my WKExtensionDelegate specifies a particular storyboard.

In Xcode, when I look at the current watch storyboard file in the File Inspector right pane, I see no special indicator marking for initial storyboard. Just in case it was listed there.

The App Programming Guide for watchOS does not explain how the connection is made either.

Any ideas?


Solution

  • So after much experimenting:

    Conclusion:

    • I cannot have mutually exclusive Storyboards in watchOS.
    • watchOS seems to merge all storyboards into one thing.
    • So when you reference a WKInterface​Controller by name, watchOS just picks the right storyboard.
    • To feature flag storyboard scenes, just make sure you don't load the wrong one.

    Evidence

    Building watchOS app extension fails with errors if more than one interface controller is designated "Is Initial Controller" across multiple storyboards. The error is: Multiple main entry points were specified. Please designate a single interface controller as the entry point of your watch application.

    I devised the following scenario and it worked:

    • Main.storyboard with interface controller identifier "Bobby".
    • Main2.storyboard with interface controller identifier "Sue".
    • Main2.storyboard interface controller Sue "Is Initial Controller".
    • Bobby has button which calls WKInterfaceController.reloadRootControllers(withNames: ["Sue"], contexts: nil)
    • Button works as expected and loads Sue interface controller scene from Bobby.