Can someone explain the window loading behavior of the Cocoa Application templates?

Hopefully this should be very easy to anyone who is used to programming Cocoa applications.

If I create a template "Document-based" program, it creates a couple of files in my project for me, that when executed, display a window, that I can supposedly manipulate and draw to. I can't find anywhere where it is specified that the "Document.xib" file is supposed to be loaded. If I delete it, it complains twice on the next execution that "Document.xib" can't be found, but never complains again, and my source control tracks no changes to any document to supress such warnings. Why is this "Document.xib" file the one loaded? I tried creating another nib file in the same project with a window and nothing happened.

Coming from a C++ and Java coding background, I'm so used to having something like a "main" yet if there is one in these templates, it's obfuscated somehow, or I'm just not seeing it. I just want to know

I also tried placing a custom view in the Document window, a subclass on NSImageView, but it forces me to write a constructor

required public init?(coder aDecoder: NSCoder)

which gets called every time. I think this constructor getting called is for undesired behavior, as it does not provide the proper view dimensions, I have no clue what to do about it, could anybody confirm what this constructor is used for?


Are there any OS X Cocoa tutorials that might help me a little further on? I know Swift, I'm not afraid of coding, I'm more afraid of using Cocoa because apple's Cocoa documentation seems to be all "tell" and no "show". I promise I have Google'd long and hard before coming here, but the questions seem to be too specific for google to turn up anything meaningful.

Accepted Answer

The answer is fairly simple, although the sequence of events is a little confusing because document-handling has become so encrusted with new features over the years.


When you launch a document-based application, it creates an "untitled" window (i.e. a new document). This is the default behavior, but it's controlled by delegate methods in your application delegate (applicationOpenUntitledFile:, applicationShouldOpenUntitledFile:). The trigger for these behaviors is the NSApplication object, via the NSDocumentController object, both of which are created automatically.


When a new document (i.e. NSDocument subclass) object is created, it eventually creates a window using either of two methods that you can override (windowNibName, or makeWindowControllers). That's the point at which you'll see the error message if your XIB file (compiled into a NIB file) is missing.


If that's all that was going on, you'd see the error message every time. However, by default, "window state restoration" is turned on system-wide. This causes your app to restore its previous windows when launched again later. If your app has quit with no windows open, then at next launch no windows will be re-opened — not even an untitled one — and so you won't see another error message until you use File -> New/Open.


(The system-wide setting is in System Preferences -> General -> Close windows when quitting an app.)


>> I'm so used to having something like a "main" yet if there is one in these templates, it's obfuscated somehow


Cocoa apps also have a C-ABI 'main' function. However, in a new Swift project, the default is to mark the app delegate class with the NSApplicationMain attribute, so the main function is supplied by the compiler. You can remove the attribute and supply your own main if you want, but you have to write it in C, and it basically just calls the Cocoa NSApplicationMain function.


>> could anybody confirm what this constructor is used for?


It's the constructor for the NSCoding protocol, which is how objects archive and unarchive themselves for persistent storage (etc). Objects in your NIB file (compiled from a XIB source file or a storyboard), such as views, are archived, so will generally get created via this init when the NIB is loaded.


>> Cocoa documentation seems to be all "tell" and no "show".


Yeah, I guess you're right about that, so if you want blow-by-blow tutorials, you'll have to dip into the wider internet. There are a couple of Apple documents that you really need to know very well, if you want to be competent at Cocoa programming (as opposed to programming by example and guesswork, which does unfortunately happen quite a lot), there are a few documents whose you contents you must know intimately, and the document programming guide is one of them:


https://developer.apple.com/library/mac/documentation/Cocoa/Reference/ApplicationKit/Classes/NSDocument_Class/


You should be prepared to read this multiple times, before and after actually writing code. The other crucial document is the event handling guide:


https://developer.apple.com/library/mac/documentation/Cocoa/Conceptual/EventOverview/Introduction/Introduction.html


I also strongly recommend you read — or at least skim — the class reference documentation for the fundamental classes: NSDocument, NSDocumentController, NSWindow, NSWindowController, NSView, NSViewController, NSEvent, NSApplication, etc, and their related protocols. I don't recommend doing this all in one sitting. Rather, if you're taking a break from something else for a while, pick one and spend 5 minutes reading. The idea is to get enough of a grasp of the details to be able to vaguely remember later that there's a detail you can go back and look up.

Can someone explain the window loading behavior of the Cocoa Application templates?
 
 
Q