I created a Mac OS X application in Xcode using storyboards. For some reason the applicationDidFinishLaunching
method in the AppDelegate is being called after viewDidLoad
in the NSViewControllers. As with iOS apps, I thought viewDidLoad
is supposed to be called before applicationDidFinishLaunching
? Do storyboards in OS X apps initialize the view controllers before the app has finished launching?
I am using the applicationDidFinishLaunching
method to register default settings into NSUserDefaults. Unfortunately, registering the default values is happening after the views in the storyboard are loaded. Therefore, when I set up the view in each view controller using viewDidLoad
, the defaults data in NSUserDefaults has not been set. If I can't use applicationDidFinishLaunching
to register NSUserDefaults in OS X storyboard apps, then how I set the defaults before viewDidLoad
is called?
To fix this issue, in the Main.storyboard
in Xcode, I turned off "Is Initial Controller" for the main window. I assigned a storyboard ID to the main window as "MainWindow". Then in the AppDelegate I entered the following code:
import Cocoa
@NSApplicationMain
class AppDelegate: NSObject, NSApplicationDelegate {
func applicationDidFinishLaunching(aNotification: NSNotification) {
let storyboard = NSStoryboard(name: "Main", bundle: nil)
let mainWindow = storyboard.instantiateControllerWithIdentifier("MainWindow") as! NSWindowController
mainWindow.showWindow(nil)
mainWindow.window?.makeKeyAndOrderFront(nil)
}
}
The app does not crash but now the window never appears. The following image displays the storyboard I'm working with:
As the question's author mentioned:
Despite Nicolas and Aaron both helpful answers (I already adquire the book you recommended, Aaron, and will start implementing the two-storyboard pattern your way, Nicolas), neither solve the specific problem of the window not showing.
Solution
You need make your WindowController instance live outside
applicationDidFinishLaunching(_:)
's scope. To accomplish it, you could declare aNSWindowController
propriety for yourAppDelegate
class and persist your created WindowController instance there.Implementation
In Swift 4.0