NSApplicationDelegate not working without storyboard

I am trying to create a macOS application without a storyboard in Xcode 8 (stable) on macOS Sierra. However, my AppDelegate not triggered. Here is the code I have:

 import Cocoa @NSApplicationMain class AppDelegate: NSObject, NSApplicationDelegate { var window: NSWindow! override init() { super.init() print("Init") } func applicationDidFinishLaunching(_ aNotification: Notification) { print("Finished launching") // Create a window window = NSWindow() // Add the view controller let viewController = ViewController() window.contentView?.addSubview(viewController.view) // Show the window window.makeKeyAndOrderFront(nil) } } 

Neither call init , nor applicationDidFinishLaunching(_ aNotification: Notification) . Any help would be greatly appreciated.

+8
xcode swift macos
source share
2 answers

You need to do a few things here.

  • Remove NSMainStoryboardFile key / value from plist
  • Subclass NSApplication and assign it to the Principal Class (NSPrincipalClass) key.

assign custom class to class

The name must be fully qualified with your module name.

  1. Manually create your delegate in a subclass of NSApplication and assign it to the delegate property.

Make sure you keep a link to your delegate object. Ive just used let here.

 class GrookApplication: NSApplication { let strongDelegate = AppDelegate() override init() { super.init() self.delegate = strongDelegate } required init?(coder: NSCoder) { fatalError("init(coder:) has not been implemented") } } 

for example, a simple delegate.

 @NSApplicationMain class AppDelegate: NSObject, NSApplicationDelegate { override init() { super.init() print("wassup") } func applicationDidFinishLaunching(_ aNotification: Notification) { print("yo! I'm alive") } } 
+11
source share

If someone is looking for a version of Swift (based on @WarrenBurtons answer).

Appdelegate

 @NSApplicationMain class AppDelegate: NSObject, NSApplicationDelegate { var window: NSWindow? func applicationDidFinishLaunching(_ aNotification: Notification) { // Insert code here to initialize your application window = NSWindow(contentViewController: RootViewController()) window?.makeKeyAndOrderFront(self) } } class RootViewController: NSViewController { override func loadView() { self.view = NSView() self.view.frame = NSRect(x: 0, y: 0, width: 600, height: 400) } } 

Subclass of NSApplication

 import Cocoa class Application: NSApplication { let strongDelegate = AppDelegate() override init() { super.init() self.delegate = strongDelegate } required init?(coder: NSCoder) { fatalError("init(coder:) has not been implemented") } } 

Record Info.plist

 <?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> <plist version="1.0"> <dict> ... <key>NSPrincipalClass</key> <string>$(PRODUCT_MODULE_NAME).Application</string> ... </dict> </plist> 

I also created the gist of this to keep me up to date with the new versions of Xcode / Swift. https://gist.github.com/florieger/7ac5e7155f6faf18666f92f7d82f6cbc

Edit: Be sure to remove Main.storyboard / MainMenu.xib, otherwise you can get two Windows in the user interface debugger.

0
source share

All Articles