Can't use storyboard custom instantiated window controller

I hit the same problem, I thought about it a bit and here is how I worked around it.

First, why do I need this for ? I wanted to inject some dependencies to my view controller hierarchy before it's built from the Storyboard. I guess that's what the API is intended to. But then, would that method be working, how would I pass the injection information down the view controller hierarchy ?

So, as the method is working without bug for view controllers, I decided to inject the information directly at the root view controller.

So, I have in my storyboard :

  • A window controller scene named "my-window-controller", which window just points to an empty view controller.
  • A view controller scene named "root-view-controller", where all the view hierarchy is described.

And wherever I want to create that view controller, I just do :

func instanciateWindowController(storyboard: NSStoryboard) -> NSWindowController {

    //  Load the (empty) window controller scene
    let wcSceneIdentifier   = NSStoryboard.SceneIdentifier("my-window-controller")
    let windowController    = storyboard.instantiateController(withIdentifier: wcSceneIdentifier)
            as! NSWindowController

    //  Load the root view controller using the creator trick to inject dependencies
    let vcSceneIdentifier   = NSStoryboard.SceneIdentifier("root-view-controller")
    let viewController      = storyboard.instantiateController(identifier: vcSceneIdentifier,
                                                               creator: { coder in
        return MyOwnViewController.init(coder: coder,
                                        text:   "Victoire !") // just pass here your injection info
    })

    //  Associate the window controller and the root view controller
    windowController.contentViewController  = viewController

    return windowController
}

with

class MyOwnViewController: MSViewController {
    init?(coder:   NSCoder,
          text:    String) { // receive here the injection information
        print(text) // use the injection information here
        super.init(coder: coder)
    }

    // Not used, but required
    required init?(coder:   NSCoder) {
        super.init(coder: coder)
    }
}