Creating a new Cocoa project in Xcode gives me the AppDelegate.swift file, which looks like this:
import Cocoa @NSApplicationMain class AppDelegate: NSObject, NSApplicationDelegate { @IBOutlet weak var window: NSWindow! }
The @NSApplicationMain attribute @NSApplicationMain described here as
NSApplicationMain
Apply this attribute to the class to indicate that it is an application delegate. Using this attribute is equivalent to calling the NSApplicationMain(_:_:) function.
If you do not use this attribute, put the main.swift file with the code at the top level, which calls the NSApplicationMain(_:_:) function as follows:
import AppKit NSApplicationMain(CommandLine.argc, CommandLine.unsafeArgv)
The instructions in the documentation do not work: the AppDelegate class AppDelegate never created. In this answer, vadian offers the following content for main.swift , which works better than the code in the documentation:
import Cocoa let appDelegate = AppDelegate() NSApplication.shared().delegate = appDelegate _ = NSApplicationMain(CommandLine.argc, CommandLine.unsafeArgv)
However, this still does not provide the same behavior as @NSApplicationMain . Consider the above main.swift with the following AppDelegate.swift :
import Cocoa class AppDelegate: NSObject, NSApplicationDelegate { @IBOutlet weak var window: NSWindow! var foo: NSStatusBar! = NSStatusBar.system(); }
The above AppDelegate.swift works with the @NSApplicationMain annotation, but when using the above main.swift it crashes at runtime with an error
Assertion failed: (CGAtomicGet(&is_initialized)), function CGSConnectionByID, file Services/Connection/CGSConnection.c, line 127.
I think this is_initialized error means that @NSApplicationMain sets things up so that AppDelegate is created after some initialization by the NSApplicationMain function. This assumes the following main.swift , which moves delegate initialization after calling NSApplicationMain :
import Cocoa _ = NSApplicationMain(CommandLine.argc, CommandLine.unsafeArgv) let appDelegate = AppDelegate() NSApplication.shared().delegate = appDelegate
However, this also does not work, because NSApplicationMain never returns! The above main.swift equivalent to a broken sentence in the documentation, since the last two lines are dead code.
So I believe that there is some way to pass a reference to my AppDelegate class as an argument to the NSApplicationMain function, so that Cocoa can do its initialization and then instantiate the AppDelegate class. However, I see no way to do this.
Is there a main.swift that provides behavior that is really equivalent to the @NSApplicationMain annotation? If so, what does this main.swift look like? If not, what does @NSApplicationMain and how to change it?