Welcome to part 10 of my infinite part series "Working without a nib". You can find part 9 here, and you can find the rest of the parts over there yonder in your favorite search engine. During my (semi-)recent podcast episode, I talked about building an app without a nib. People seem to be especially interested in how you create the main menu of a Mac app without a nib (or xib, or storyboard). Many years ago I posted a sample nibless application on my old blog, but since then … much has changed. Given the renewed interest, I've decided to post a brand new sample application. You can download the Xcode project now. I call the app "High Nibless". No, seriously, it's "NiblessMenu".
By popular demand, I've written the app in Swift. Which means it won't compile anymore in a few weeks. Caveat Swiftor. I could have posted the source code on GitHub, but I decided to host it on my web site instead. The problem with GitHub is that no good deed goes unpunished: once you push your source code there, other people send pull requests, open new issues, and generally nag you as if they paid you to work. I'm still happy to accept feedback about the code, however, as long as your comments and questions fit on the memo line of a signed check made out to me.
In a nutshell, to create a Mac main menu programmatically, you just need to create a new
NSMenu instance, populate the menu, and set your instance as the
mainMenu of the application (AKA
NSApp) This can all be done using public API allowed in the Mac App Store. You'll notice that there is no
NSApplicationMain in the app. Instead we call the
run(). The main purpose of
NSApplicationMain is to load objects from your app's main nib or storyboard, so it's not needed when your app is nibless.
I've included a typical set of menu items in the sample app's main menu. It's not intended to be exhaustive. A good way to discover how to add other menu items is to create a new Cocoa app in Xcode and use the main menu in the storyboard or xib as a guide. You can examine the individual menu items to see their properties and connections. That's mostly how I came up with NiblessMenu.
The source code is released under my standard SHAG license: if you use it in your app and become rich and famous while I linger in poverty and obscurity, I will Silently Hold A Grudge.