Building Your First Cocoa Application
Welcome to Colour Me Cocoa.
Looks like you're new here. If you like what you see, you may want to subscribe to my RSS feed, or if you prefer sign up to receive email updates.
Thanks for visiting!
Today I’m going to take you on a journey through building your first cocoa application. We’re going to start by defining a simple problem, then build a user interface and through the wonders of cocoa bindings connect it all up to a controller object.
I am going to use the challenge from Chapter 4 of Cocoa Programming For Mac OS X by Aaron Hillegass as our problem. The solution requires the user to be able to enter a string into a text field, press a button, and have the application display another string indicating the length of the original string.
For example if I type in “Colour Me Cocoa rules!” and click the button the application will respond with
“Colour Me Cocoa Rules!” is 22 characters long
Sounds simple enough… So if you have just under an hour or so to spare then follow me!
Create a New Cocoa Application
Open Xcode and create a new project. Select Cocoa Application from under the Application header. I’ve called mine Challenge4, but you can call yours whatever you like.
You should have a list of files in front of you, locate the one called MainMenu.nib (English). This is your user interface file. Double click it and wait. Interface Builder will open and you will be presented with the default interface builder windows. You might find it useful to use the Hide Others command from the Interface Builder menu as you will have quite a few windows on screen.
Building the User Interface
Because we are going to use cocoa bindings we won’t be needing a button on our interface, but we will require 2 NSTextField objects. Using the palletes window (found under tools) choose the cocoa-text menu and drag System Font Text and the NSTextField box below it onto the window entitled “Window”.
Re-size and organise your 2 NSTextField objects and the window itself. You will notice little blue dotted lines appear when you bring these objects close to the edge of the window. Use these guides to help lay out and align your objects. When you have finished you should end up with something similar to this:
This looks great so far, but the “System Font Text” string and the title of the window look wrong. Lets fix them. From the Tools menu select Inspector. Depending on what you have selected in your main window, the inspector window will give you different options to edit. Change the “Window Title:” to something different, I’m using “String Length Calculator”, and change the “System Font Text” to be “Enter a string above”.
Creating a Controller Class
Now that you have built a user interface it’s time to create a controller class. This class will be responsible for ensuring the program knows what to do with the string you enter into the text field.
In interface builder find the window entitled “MainMenu.nib (English)” and choose the Classes heading. Scroll to the left and select NSObject. Every class within Cocoa ultimately descends from NSObject.
While NSObject is selected, choose Subclass NSObject from the Classes menu item. This will create a new Object called “MyObject”. Rename this to “LengthCalculator”.
Now that you have created a class, it’s time to create the files that go along with it. With LengthCalculator selected choose Create Files for LengthCalculator from the Classes menu. Make sure all the check boxes are ticked and that you are then hit the Choose button.
Save your interface builder files and return to Xcode. You should now have LengthCalculator.h and LengthCalculator.m files in your project.
Writing The Controller Code
First we need to flesh out our header file. Open LengthCalculator.h and modify it as follows:
/* LengthCalculator */
#import <Cocoa/Cocoa.h>
@interface LengthCalculator : NSObject
{
NSString * inputString;
}
-(NSString *)outputString;
@end
The above code defines how LengthCalculator works. Lets take a closer look at it.
@interface is the signifies the beginning of our definition. Likewise @end signifies the end of our definition. Everything in the header should be contained within these two keywords.
LengthCalculator : NSObject declares that LengthCalculator is a sub-class of NSObject, or that NSObject is LengthCalculator’s super-class. In Objective-C each class can only have one super-class.
NSString * inputString; contained within the curly braces defines an NSString object called inputString. This will soon be connected to our NSTextField box in the UI.
-(NSString *)outputString; is a method that we will have to implement in LengthCalculator.m. It returns an NSString object and we will connect that to the other NSTextField object on our user interface. This will allow us to display our answer.
Now for the meaty bits. Open LengthCalculator.m and modify it to contain the following:
#import "LengthCalculator.h"
@implementation LengthCalculator
+ (void)initialize
{
[LengthCalculator setKeys:
[NSArray arrayWithObjects:@"inputString", nil]
triggerChangeNotificationsForDependentKey:@"outputString"];
}
- (NSString *)outputString
{
if ([inputString length] > 0) {
return [NSString stringWithFormat:
@"\"%@\" is %d characters long", inputString, [inputString length]];
}
return [NSString stringWithFormat:@"Enter a string above"];
}
@end
This is the implementation of the LengthCalculator controller class. You probably guessed that from the @implementation keywords right?
Because we are going to use cocoa bindings to wire up our user interface we need to implement the + (void)initialize method. This method is called just before the class receives its first message—even if that message would not create an object.. The code within the initialize method might look a bit scary, but it’s really very simple.
In this code we are telling the LengthCalculator object to create key bindings, we are doing this with the setKeys method. The key bindings that we have created are defined in the NSArray that is created. Specifically we have added inputString as a key.
triggerChangeNotificationsForDependantKey is a mouthful of a method call. But it does just what it seems. It takes the keys in the array (ie. inputstring) and then notifies the dependent key outputString if it changes.
Re-read the above sentence again because it is important. This is how we set up our cocoa bindings. Now whenever inputString changes, the outputString method will be called.
- (NSString *)outputString
{
if ([inputString length] > 0) {
return [NSString stringWithFormat:
@"\"%@\" is %d characters long",inputString, [inputString length]];
}
return [NSString stringWithFormat:@"Enter a string above"];
}
If you have been reading the other articles on this site then it will not take you too long to figure out how the outputString method works. I’m not going to explain it here, if you’re stuck then go back and read about controlling the flow of your program and format specifiers in the FizzBuzz solution.
Connecting the User Interface to the Controller
Nearly there. Just one thing left to do. We need to connect everything together so that it works. Open up MainMenu.nib again. Find and highlight LengthCalculator under the classes heading in the MainMenu.nib window. Now select Instantiate LengthCalculator from the Classes menu.
Look at the shiny blue box you just created. Isn’t it pretty? This is a representation of a LengthCalculator object. Back in the Palletes window there is a similar blue box in the menu along the top. Click it and you will now be looking at the Cocoa-Controllers pallete.
Drag the middle green box, an NSObjectController, next to your blue box in the MainMenu.nib window. You can re-name it if you want, but I am going to leave it as is.
Now that we have instances of both LengthCalculator and NSObjectController, we need to tell the NSObjectController that it is in charge of the LengthCalculator. We do this by control clicking on the NSObjectController and dragging to the LengthCalculator.
The inspector will pop up with content highlighted. Click the connect button to seal the deal.
With the inspector still open change the drop-down from Connections to Attributes and use the Add button to create some keys. You guessed it, inputString and outputString.
Now select the top NSTextField, back in the inspector change the drop down to Bindings. Hit the value button to expose the details. Select inputString from the Model Key Path drop down. You have just told the NSTextField to bind itself to the inputString key-binding.
Note that I have also ticked the Continually Updates Values checkbox. Without this checked the user has to press enter or click outside the NSTextField before it will signal that it has been changed. With it checked every key press will signal a change.
Do the same for the other NSTextField, only this time bind it to outputString.
The Moment Of Truth
So the time has finally come. Save your files and hit the Build and Run in Xcode. If you’ve follow all the steps then your first cocoa program will launch and work as intended. Pat yourself on the back.
If something goes wrong, try and work it out, go back and read through the instructions again. Try starting from scratch, sometimes stupid little mistakes cause the biggest problems and they are an absolute nightmare to find. Over time you will learn what these mistakes are, but for now it will probably be quicker to start from scratch.
Remember, if you’re still having problems then leave a comment. We’ll try and set you on the right path again.
More Tutorials
I find the best way to learn is by doing. And the more I do the more I learn. These little applications don’t take very long to make so set yourself a problem and get cracking on your own.
I’m not going to leave you hanging though. Here are a few other tutorials I’ve used and recommend:
- Cocoa Dev Central: Learn Cocoa
- Cocoa Dev Central: Learn Cocoa Two
- Currency Converter on ADC
- Currency Converter using Bindings on ADC
March 31st, 2007 at 5:30 am
To get it to compile i had to remove the quotes around %@ in the following line:
return [NSString stringWithFormat:
@” “%@” is %d characters long”, inputString, [inputString length]];
Is there a way to escape the quote?
Nice tutorial. Thanks for taking the time to share it.
March 31st, 2007 at 5:43 am
You can use the backslash character to escape the quotation marks.
return [NSString stringWithFormat:
@” \“%@\” is %d characters long”, inputString, [inputString length]];
It’s in my original code but the html conversion stripped it. I’ve updated the post now so that they are in the code.
March 31st, 2007 at 6:19 am
Doh! I should have just tried that :), as it’s hardly a Cocoa peculiarity.
March 31st, 2007 at 3:29 pm
April 1st, 2007 at 12:20 pm
This demo shows how to do similar thing on Unix with GNUstep, another implementation of OpenStep, as Cocoa.
http://www.gnustep.org/experience/DevelopmentDemonstration.html
While GNUstep is not on a par with Cocoa, it is a good solution for cross-platform development.
April 4th, 2007 at 9:17 am
[…] Building Your First Cocoa Application | Colour Me Cocoa (tags: application development tutorial mac osx cocoa) This entry is filed under Links. You can follow any responses to this entry through the RSS 2.0 feed. You can leave a response, or trackback from your own site. Leave a Reply […]
April 5th, 2007 at 12:58 pm
man… this is my first attempt at building an app and you made it an easy success… thanks for empowering the noobs!
April 13th, 2007 at 10:58 am
hi nice site.
April 30th, 2007 at 2:18 am
Close.
+initialize is called just before the class receives its first message—even if that message would not create an object. Any message to the class will result in +initialize being called, as long as it’s the first message to the class (each class receives +initialize no more than once).
BTW, this article has been submitted to reddit.
April 30th, 2007 at 3:10 pm
Thanks for pointing that out Peter. I’ve updated the article to reflect your comments.