Writing a GUI application is no simple feat. Apple has done its best to implement an API which helps control the complexity inherent in programming even a simple GUI driven application. At first it may seem that Apple’s interface libraries add a lot of unnecessary abstraction. However, once you move past toy examples, Apple’s API design decision present some clear advantages.
Probably the toughest thing for people to wrap their head around (besides reference counting) is delegation. Delegation is actually a fairly simple pattern that allows objects to communicate with each other without have to mix up their implementations. That is delegation helps you control the complexity inherent to GUIs. If an object needs to know something about how another completely different object works then chances are that both object will get complex and their implementation intertwined. Delegation and protocols control this complexity.
A text field by itself is a useless thing. By defining a protocol, a text field can let a delegate know that certain things are happening. The delegate can then (without caring how a text field works) respond to user generated actions.
Again. A Delegate says to the text field, “I’m the application logic, let me know when something happens to you since I’ll know how to handle it cuz, hey, you’re just a measly text field, you don’t know anything.”
Text Field says, “I’m just a measly text field, I don’t know anything about anything. But I do know something about text input. I’ll let you know about anything interesting that happens. You want to know about something, then implement some methods from my fancy Delegate Protocol“.
Remember protocols are simply a collection of method signatures that have been group logically together. They have not been implemented. They simply show that if you do implement them, an object will attempt to call these methods on the delegate.
Again this is starting to sound abstract, let’s see how this works in reality. You are going to write a simple Cocoa app.
Launch XCode and start a Cocoa project by going to the File menu and selecting New Project. You’ll confronted with a dizzying array of options in the following window. You have three categories on the lefthand side, iPhone OS, User Templates, and Mac OS X. Select the Mac OS X category, and from that list select Cocoa Application. Click the Choose button at the lower left.
Create a folder called FirstCocoaApp on your Desktop (or wherever you want really). Before we get too far we should get a lay of the land. First things first, we should change the editor behavior to work in single window mode otherwise your screen will be cluttered very quickly. Open up the Preferences menu from the file menu. Look at the General options and make sure the two Editing radio buttons are selected. Make sure to click Apply then OK.
On the left you’ll again find something will remind you of iTunes. This is the primary organizational interface in XCode, the Groups & Files list. All the relevant source files, resources, and references are stored under the first item, which represents you project. Targets stores different “build instructions”, SCM handles revision control integration (no Git support yet), followed by a Project Symbols, and Smart Folders (you can make you own). The other things in the list should be obvious from their names.
Go ahead an disclose all of the folders in your project. It should look something like this:
All your source code will go in the Classes group. Groups in XCode do not need to reflect the file system at all. However if you decide to rearrange files in Finder, your groups will get confused and you’ll need to re-add moved files to your project. You should feel free to make groups at will and organize them however you see fit. Just note that Apple’s default grouping is a good starting point, and it also means that people won’t be confused when they look at your project.
The Other Sources group will contain two files. The file that ends in _Prefix.pch is just prefixes that will be put in front all of your source files. You can also declare project wide declarations here. Don’t over do it.
Then you have main.m. This just kick starts your application. Below this you have Resources. Nib files (now called .xib files) live here as well as metadata about your project. Internationalization files also go here. If you’re going to add a lot of image assets to your project you should probably create an Images group inside the Resources group and keep your image files there.
Below Resources you have Frameworks. These are the Apple frameworks that your project links against. You can’t just simply create an NSArray object in your source code. You need to make sure you’ve added the Cocoa framework to your project. Similarly, you can’t create UIs using Apple’s widgets without including the AppKit framework. Right click on the Frameworks group and select Add > Existing Frameworsk…. This will create an Open Dialog that’s focused on the frameworks that available on your system. There’s a lot of stuff in there. The iPhone has a different set of frameworks since it has a very different set of capabilities.
Let’s create a simple Cocoa app. You might have gone through something similar with the Hillegass book, but I recommend going through it again unless you really think you understand the concepts behind delegation.
Before we get started type, Command-R to build and run your application. It should launch and you should see an empty window, the main menu should also change to reflect that your application is running. You didn’t even have to write any code. Go ahead and quit your application.
First thing we want to do is add a button to a window. We could do this programmatically, but there is no reason to, Interface Builder can do all the hard work for us.
In your Resources group double click on the MainMenu.xib. This Nib file (.xib just reflects that Nib files are represented as XML now, that doesn’t mean they can be edited by hand, it just makes it simpler for version control system like to SVN and Git to track changes) represents the interface of your application. When Interface Builder launches you’ll be presented with three important windows. The first is the window representing the contents of your nib file. The other two are the Inspector and the Library. You can open these via the Tools menu.
The Inspector is how you customize the appearance and functionality of a Apple UI component without writing code. The Library is where you can grab and drag and drop new UI components to add to your interface.
In your nib file you should see that you already have a window. At the bottom of the Library there a search field for filtering the contents of the library. Type in “NSButton”. The first one should be Push Button. Drag one from the Library and onto your window. You can put it wherever you like. Double click on it and give it a name.
That’s all there is to making buttons. Before we start worrying about how to make it do something, let’s go ahead and add a text field. In the same Library search field type “NSTextField”. Drag the one called Text Field to the window and put it above the button.
Switch back to XCode and build and run your program. Great, a button and text field, neither of which do anything.