NSWindowController subclass in Swift project

Peter Wood in Swift
11 Jul 2014, 15:05

How are you doing?

Some more tips from my development experience in Swift.

What’s to your mind the percentage of Mac applications where NSWindowController and its subclasses are used? Should be high I believe.

But if your application is in Swift and you’d like to use NSWindowController subclass, a surprise is waiting for you: init(window: NSWindow?) is designated initializer, and init(windowNibName: String?) is convenience initializer.

That means:
– I cannot override it
– I cannot create my own initializer in the subclass and call super.init(windowNibName: “WindowNibName”) in it.

Total nuisance, yeah. What adds to confusion is the initializer generated by Xcode at NSWindowController subclass creation.

init(window: NSWindow?) {  super.init(window: window)  // Initialization code here.  }  

As a result, it seems that we cannot call init(windowNibName: “WindowNibName”) at all!

I prefer to use mainly init(windowNibName: String?) to create window controller, and call it either directly or in custom init. But I cannot do this in Swift due to reasons I’ve stated above.

Is there a way out?
Yes! There are even two of them!

1. Get rid of all the constructors in our class. Thus we’ll be able to call the required Convenience Initializer of the base class.

var controller = MyWindowController(windowNibName:”MyWindowControllerNib”)  

Initialization can be done by windowDidLoad() method in this case.

2. keep the init(window: NSWindow?) constructor generated by Xcode; and override the following methods:

 override var windowNibName : String! {   return "MyWindowControllerNib"   }  

The object should be created as follows:

var controller = MyWindowController(window:nil)

In this case, we’ll be able to both use the initializer created by Xcode and create our own custom initializers.

UPD: Seems that I’ve missed a very simple yet obvious method – overriding all designated initializers of the base class.

So here we have the 3rd method: override all the designated initializers, that is, add to your subclass the following:

      init()  {          super.init()      }            init(window: NSWindow?) {          super.init(window: window)          // Initialization code here.      }        init(coder: NSCoder!) {          super.init(coder: coder)          // Initialization code here.      }  

Thus we’ll be able to call the required Convenience Initializer of the base class.

  var controller = MyWindowController(windowNibName:”MyWindowControllerNib”)  

It’s up to you to decide which method to use.

Stay tuned for more news.