How to replace my .xib file with pure Swift 3?

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?
+2
source share
2 answers

Answer the question number 3:

  • Create the Swift main.swift file.
  • Replace main.swift code with

     import Cocoa let appDelegate = AppDelegate() NSApplication.shared().delegate = appDelegate _ = NSApplicationMain(CommandLine.argc, CommandLine.unsafeArgv) 
  • Remove @NSApplicationMain in AppDelegate .
  • Delete the NSMainNibFile key / value NSMainNibFile in Info.plist .
  • Delete the .xib file.
0
source
  • The name of your XIB file is stored in your Info.plist. You can directly modify it by selecting the Xcode project file and clicking the "Information" tab, or you can make changes from the "General" tab in the "Main Interface" section.

  • At the top level of each standard MainMenu.xib is the AppDelegate object. This object is the one that receives all messages from the application delegate. It is connected to the delegate output of the placeholder application object.

  • To reproduce this behavior, you need to subclass NSApplication and change the setting of your target parameter, "Main Class" Info.plist, to reflect the new subclass. In your subclass, you can override something like finishLaunching() to create an application delegation object and customize it. Remember, however, when you do this like this, you need to make sure that your new delegate has a strong link because it no longer belongs to the nib file. I recommend adding a strong property to your subclass, perhaps something like strongDelegate .

0
source

Source: https://habr.com/ru/post/1265644/


All Articles