I am making a macOS Cocoa application that only works on the menu bar. When I initially created the project, Xcode gave me a file called MainMenu.xib . This MainMenu.xib file MainMenu.xib not contain anything that is relevant to my menu bar application, so I want to delete it.
Cocoa's entry point, the NSApplicationMain function , "downloads the main nib file from the main application package." I read elsewhere that Cocoa finds the βmain nib fileβ by consulting the NSMainNibFile key in my Info.plist , which was set to the MainMenu line. I deleted the NSMainNibFile key, and my program still behaved the same way. From this, I assumed that Cocoa saw the absence of this key, and therefore it skipped the nib / xib download step.
Since my MainMenu.xib file MainMenu.xib no longer referenced anywhere, I deleted it (which removed some innocent looking links from my project.pbxproj ). However, after uninstalling MainMenu.xib my application no longer works. The applicationDidFinishLaunching method in my AppDelegate class AppDelegate not called!
That means two things. Firstly, this means that Cocoa magically still finds my MainMenu.xib file, even if NSMainNibFile no NSMainNibFile (and Cocoa still finds the file if I rename it to Foo.xib ). More importantly, this means that my application still needs something in my MainMenu.xib . Here is the full MainMenu.xib :
<?xml version="1.0" encoding="UTF-8"?> <document type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="3.0" toolsVersion="11762" systemVersion="16D32" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none" useAutolayout="YES" customObjectInstantitationMethod="direct"> <dependencies> <plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="11762"/> </dependencies> <objects> <customObject id="-2" userLabel="File Owner" customClass="NSApplication"> <connections> <outlet property="delegate" destination="Voe-Tx-rLC" id="GzC-gU-4Uq"/> </connections> </customObject> <customObject id="-1" userLabel="First Responder" customClass="FirstResponder"/> <customObject id="-3" userLabel="Application" customClass="NSObject"/> <customObject id="Voe-Tx-rLC" customClass="AppDelegate" customModule="Foo" customModuleProvider="target"/> </objects> </document>
I think the problem is that my MainMenu.xib belongs to my AppDelegate class, and Cocoa uses this to instantiate the AppDelegate class and then calls the applicationDidFinishLaunching object. This is confusing because I thought the @NSApplicationMain annotation in my AppDelegate class AppDelegate sufficient.
I have a few questions as a result:
- How does Cocoa (i.e.
NSApplicationMain ) find my MainMenu.xib file? What is a Cocoa search procedure? How do I tell Cocoa to skip this download step? - What is my
MainMenu.xib file? That is, how does Cocoa interpret the MainMenu.xib file MainMenu.xib and what does it do as a result? In particular, how AppDelegate this file create an instance of the AppDelegate class? - How to restore this logic exclusively programmatically in Swift 3 so that I can delete the
MainMenu.xib file? What APIs do I need to use?
source share