|Home » Learning Curve
Cookie Tin Tips III
This series is directed to potential switchers. It's about Unix. Remember when reading that Unix is considered more than an operating system: it's a way of thinking.
NeXTSTEP applications look a lot different from applications on other platforms where they're often single file entities. For example: Windows programs start with their MS-DOS header which in turn refers to an 'NT header' which has information about where everything is located in the file.
Executables have (relocatable) code, data sections, and resource sections. The latter are menus, images, dialog scripts, the works. It's all contained in the same file and the program loader reads the headers to find where everything is at runtime.
NeXT applications are 'packages': a number of files organised in a file hierarchy. At the top is the application itself, so to speak: the name with the extension 'app' tacked on. There is nothing else at this level.
Immediately below the 'app' file (which is actually a directory) is a directory called 'Contents'. This directory contains at least the file 'Info.plist' which is an XML-based configuration file that tells the system what's available.
These XML files (called property list files) are organised around a key/value system. Some of the more important keys in Info.plist are the following, taken from the ACP application 'Fortune'.
The 'CF' prefix on many of the key names stands for 'Core Foundation', a module in OS X; the 'NS' of course refers to NeXTSTEP.
- 'CFBundleExecutable' gives the name of the executable; where this is located is determined by the hardware platform you're running (yes NS apps are portable across multiple hardware boundaries).
- 'CFBundleIconFile' tells the system what image is supposed to be used to depict the application in the shell.
- 'CFBundleIdentifier' is used by the defaults system. Any number of things in the application run can result in changes to user preferences; this value tells the system where to store these changes.
- 'CFBundlePackageType' tells the system what kind of package this is. 'APPL' is used for applications.
- 'CFBundleSignature' is used with the HFS file system. It can be 'branded' onto files created with this application.
- 'NSMainNibFile' tells the system where to find the main 'NIB' of the application. 'NIB' stands for 'NeXTSTEP Interface Builder' - the program Jean-Marie Hullot wrote for NeXT. NIBs contain more than resource scripts on other platforms: they contain both code and connections to the executable.
- 'NSPrincipalClass' tells the system which NeXTSTEP/Cocoa class is to initialise this app. This makes sure the class is loaded so that the executable's control flow will reach something that is already loaded into the process address space. 'NSApplication' is the typical way Cocoa apps start.
Below the Contents directory you'll normally find two more directories: MacOS and Resources. The MacOS directory contains the actual executable for the Macintosh; a run though Resources will show it contains NIBs with typical GUI resources.
Below Resources you will also find a number of subdirectories with the extension 'lproj' ('language project'). OS X will run in any of a number of languages automatically depending on your system settings.
If the app you're running has language project directories for each then the system will choose the one you really want; if it doesn't then the system will still choose the most appropriate one for you. Common here is a single directory English.lproj for resources in the English language.
[English does not mean all 'dialects' of English: Australian English is different, so is British English, and so forth. There are special names for them all.]
In each lproj directory you should also find a file named 'InfoPlist.strings' - a Unicode file in a special XML format known as a strings file: it contains only string keys and values.
InfoPlist.strings will have your copyright information and other assorted stuff for display in the default About box. Fortune's InfoPlist.strings looks like this:
CFBundleName = "Fortune";
CFBundleShortVersionString = "Fortune version 1.5";
CFBundleGetInfoString = "Fortune version 1.5, Copyright 2005 Rixstep.";
NSHumanReadableCopyright = "Copyright \U00A9 2005 Rixstep. All rights reserved.";
Note the '\U00A9': this is an escape sequence; the file is Unicode; '\U00A9' gives you the 'copyright' symbol '©'.
More Than You Know
NIBs are more than their counterpart on Windows - or their counterpart on any other platform. They contain actual code. Explaining how all this works is beyond the scope of this series - but a common way of describing them is as 'freeze dried code': things are set, class code is initialised, and when the system loads the app it's all 'unarchived' and runs 'just like that'.
It's fairly unbelievable - and takes GUI program development to where it should be - but on no other platform do you come close to this.
When you're running Finder, the default GUI shell on OS X, your applications look like ordinary applications. They don't appear to have any 'app' extension. You can double click them and the applications will start.
But they're really directories containing all the logic of the application and the extension 'app' is hidden from view.
Because the resources are separated from the executable and not in the same file and because the Apple developers tools are free, ordinary users can with some work actually change the way their applications behave.
With a bit of practice - and patience - almost anyone can get good at this - and without ever having written a line of code in their lives. You can change keyboard shortcuts, menu titles, window layouts, captions on push buttons, tick boxes, radio buttons - almost anything you want. The app will remain the same but you can make it 'look' and behave from the GUI POV in a way that suits you better.