Subclassing NSWindowController with Swift

Swift is a new programming language that builds from Objective C.  Since I liked working with Objective C it only seemed natural to spend time learning Swift.  This article uses Xcode 7.2.1 and Swift 2.1.1.

The task considered in this article is to subclass NSWindowController so that additional data can be stored.  Initializing this new class with a NIB file name runs into problems.  init(windowNibName: String?) is a convenience initializer.  If a new initializer init(data: MyObject, windowNibName: String?) is created then all the designated initializers must be overriden.  Initialization cannot easily be done in windowDidLoad() because this does not allow data to be passed in.  There are two designated initializers in NSWindowController but there is a third designator init() that causes problems with overriding the designated initializers.  Without the ability to override the desingated initializers successfully then only the designated initializers can be called from the new initializer.

Peter Wood covers three possible approaches but they no longer seem to work in this case with more recent versions of Xcode and Swift.  Here is another approach.

import Cocoa

class MyViewController: NSWindowController {
    
    var data: MyObject!
    
    override var windowNibName : String! {
        return "MyViewController"
    }
    
    convenience init(data: MyObject, windowNibName: String) {
        self.init(window: nil)
        self.data = data
    }

    override func windowDidLoad() {
        super.windowDidLoad()
    }
    
}

The windowNibName is overriden so that when NSWindowController loads the window it can find the right one.  Then we create a new initializer that calls a designated initializer but passes in nil for the window.  Note that by using a convenience initializer the designated initializers do not need to be overridden in this subclass.  self.init is used instead of super.init because we are not chaining inits but we are delegating.  This forces NSWindowController to load the window.  Then we set our data.

Categories