TweetFollow Us on Twitter

Finishing Our First Cocoa App

Volume Number: 20 (2004)
Issue Number: 4
Column Tag: Programming

Getting Started

by Dave Mark

Finishing Our First Cocoa App

In last month's column, I told you about my fabulous trip to Big Nerd Ranch for some down home Cocoa training with Aaron Hillegass and crew. We then started on our first in a series of Cocoa programs. We used Xcode to create a new project (named RandomApp), then used Interface Builder to edit the nib file and create the RandomApp user interface.

Figure 1 shows the final configuration of the window we laid out in Interface Builder. The top button is used to seed the random number generator. Press the second button to generate a new random number. The new number is displayed in the text field below the two buttons. In Figure 1, the text field is selected and the blue, dashed lines show the window was being resized to leave the proper amount of space below the text field and to the right of the two buttons and the text field.


Figure 1. The final window, showing two buttons and a text field.

Once the window was laid out to our satisfaction, we selected Test Interface from Interface Builder's File menu to take the interface for a test drive.

So what's next? Aha! Glad you asked...

What's Next

Unless you've been patiently waiting with both Xcode and Interface Builder running in the background, chances are good that you saved last month's efforts and have since quit both apps.

OK, let's get back to work.

Launch Xcode and open last month's Xcode project. I saved my copy in my Documents/Projects/ directory in a subdirectory named RandomApp. Find and launch RandomApp.xcode.

When the project window appears, open the triangle to the left of the NIB Files group to reveal the project's nib file, MainMenu.nib. Double click on the nib file to open it in Interface Builder.

Outlets and Actions

Your next task is to create a subclass of NSObject that we'll use to respond to clicks in the Seed Generator and Generate Random Number buttons. The class will also modify the text field to display the newly generated random number when the Generate Random Number button is pressed.

The methods we create to respond to the button clicks are called actions. We'll create a unique action that we'll associate with each button.

We'll also need an instance variable that points to the text field so we can change it from the method tied to the Generate Random Number button. This kind of object pointer is known as an outlet.

When you start a new program, you'll almost always be thinking in terms of actions and outlets. This might be a little fuzzy, but hopefully by the time you get RandomApp up and running, this will be a bit clearer.

Let's start by creating our new class. You'll do this in the main Interface Builder window. The folks at Big Nerd Ranch like to refer to this window as the "doc" window. Cool with me. The doc window is shown in Figure 2. Don't worry too much about what all the different icons mean. We'll explore them all in future columns.


Figure 2. Interface Builder's "doc window".

For now, click on the doc window's Classes tab. If you don't see NSObject in the leftmost pane (See Figure 3), scroll to the left using the scrollbar at the bottom of the doc window. Click on NSObject to select it. NSObject is the root class for all Cocoa classes. Note that all classes start with a capital letter. When you create your class, you'll follow this convention.


Figure 3. The NSObject class selected in the Classes tab of the doc window.

To create your NSObject subclass, select Subclass NSObject from Interface Builder's Classes menu. A new class will appear in the second pane. Change the name to Foo, then hit return to lock in the name change. The name Foo should appear immediately after FirstResponder in the second column.

Now let's add our outlet and actions to our new Foo class.

With the Foo class name selected in the second column of the doc window, select Show Info from the Tools menu to bring up the inspector window. As you can see in Figure 4, the inspector currently shows 0 outlets and 0 actions for the Foo class. We'll start off by adding an outlet.


Figure 4. The inspector, showing 0 outlets and 0 actions for the Foo class.

Remember, an outlet is an instance variable that is a pointer to an object. Instead of doing all the work in code, we're going to use the point-and-click power of Interface Builder to add the class, then add the outlet instance variable and action methods to the Foo class and, ultimately, to generate the source code files that implement the Foo class to the Xcode project. Once you get used to this process, you'll never want to create classes from scratch again. Incredibly powerful stuff.

To add an outlet to Foo, click on the Add button in the lower-right corner of the inspector window (Figure 4). Be sure that the Outlets tab is selected or you'll be adding an action instead. Once you click the Add button, a new outlet will appear. Name the outlet textField, then set the outlet's type to NSTextField using the popup menu in the second column. Basically, you've just told Interface Builder to add an instance variable to the Foo class with the name textField and the type NSTextField. You've used the interface to do this instead of typing the source by hand.


Figure 5. Set the outlet's type to NSTextField from the popup menu.

Now let's add a couple of actions. Click on the Actions tab and click the Add button. Name the new action seed:, being sure to include the trailing colon. The colon is actually part of an Objective C method name. Note that by convention, Objective C method names always start with a lower case letter (as opposed to class names which, as mentioned, start with an upper case letter).

Next, add a second method. Call it generate: (yup, remember the colon). When you are done, your inspector window should look like the one shown in Figure 6.

    If you find your inspector window getting out of sync, it might be because you have clicked on a different Interface Builder object. The inspector always reports on the currently selected object. Click on a window, the inspector shows the window's properties. If you do get lost, go back to the doc window, click on the Classes tab, scroll all the way to the left, then click on the NSObject class, then on the Foo subclass. The title of the inspector window should now be Foo Class Info. If the contents of the window do not match Figure 6, be sure to select Attributes from the popup menu at the top of the inspector window.


Figure 6. The inspector window showing my two actions.

Generate the Source Files

You've now laid out the pieces that make up your Foo class. You've got a pointer to an NSTextField, as well as a pair of methods you'll want called when the user clicks the Seed Generator or Generate Random Number buttons.

Your next step is to generate the source code that defines the Foo class and add that source code to your Xcode project. Fortunately, Interface Builder can do all this for you with one menu selection.

Make sure that the Foo class name is selected in the second column of the doc window. Now, select Create Files for Foo from the Classes menu. A sheet will appear (See Figure 7) that asks you where you'd like to save the files, what type of files to create, and to which target to add the files. Unless you've done some monkeying around, the defaults will probably be just fine. You'll save the files in your main project directory (mine is called RandomApp). You'll want to create both a Foo.h and a Foo.m file. Foo.h is the include file that contains your class declaration. Foo.m contains the actual class definition (the seed: and generate: source code, for example).

The target is the specific Xcode build you want these source files to be part of. Since we only have one target, this is an easy choice. Make sure the RandomApp checkbox is checked.


Figure 7. Saving the Foo class files.

Click the Choose button to add the source files to your project. Notice that two new source code file names appear in your Xcode project window in the Groups & Files pane. Typically, the two names will be appended to the list in the Other Sources group (See Figure 8). Feel free to drag them into another group or subgroup as you like.


Figure 8. The files Foo.h and Foo.m are added to the Groups & Files list.

Create and Connect a Foo Instance

Before we edit the source code, there's just one more task ahead of us. We need to create an instance of the Foo class, then connect the outlet and actions to the appropriate objects. This will become clearer in a moment.

Go back into Interface Builder.

In the doc window, click on the Foo class name in the second column. Select Instantiate Foo from the Classes menu. To see your new object, click on the Instances tab in the doc window.

As you can see in Figure 9, a new icon has appeared. In the doc window. Note the tiny explamation point in the lower left corner of the Foo icon. If you hover your cursor over the exclamation point, a tool-tip will appear saying "Unconnected outlet(s) (textField)." We've declared an outlet named textField but we haven't connected it to a text field. Let's fix that.


Figure 9. The Foo instance in the doc window. Note the message about Unconnected outlet(s).

Control-drag from the Foo instance to the text field below the two buttons in our application window. As you can see in Figure 10, when you start the control-drag, a little square will appear in the Foo icon, then a line will follow your cursor as you drag to the text field. Once the text field is highlighted with a surrounding rectangle, you can release the mouse button.

To complete the connection, click the Connect button in the lower-right corner of the inspector window.

The purpose of this connection is to fill the Foo object's textField instance variable with a pointer to the window's text field so we can modify the contents of the text field in our source code.


Figure 10. Control drag from Foo to the text field below our two buttons.

Our next step is to connect each of our two buttons to the appropriate method using the same technique.

Control-drag from the Generate Random Number button to the Foo instance. In the inspector window, you should see a list of Foo methods to choose from. Click on generate: and then click the Connect button (See Figure 11). You can also double-click on generate: instead.

If your inspector window gets out of sync, be sure that Connections is selected from the popup at the top of the window, then make sure that the Target/Action tab is selected. Finally, be sure that you dragged from the Seed Generator button to the Foo instance.

Next, let's connect the Seed Generator button to the seed: action. Control-click from the Seed Generator button to the Foo instance in the doc window. Next, select seed: and click the Connect button.


Figure 11. Click the Connect button to connect the Generate Random Number button to the generate: method.

That's it! Save your changes. This last step is very important as we are going to switch over to Xcode and we want to be sure we are dealing with the latest version of the .nib file.

Editing Your Source Code

In most programming projects, editing the source code is by far the biggest step to building your project. Because of the power of Interface Builder and the reusability of all the existing Cocoa objects, our source code changes will be pretty minimal.

Let's take a look at Foo.h.

Find Foo.h in the Groups & Files pane. Click on it. If the source code does not appear in an editing pane, select Show Embedded Editor from the View menu.

Here's the source code that Interface Builder placed in Foo.h:

/* Foo */
#import <Cocoa/Cocoa.h>
@interface Foo : NSObject
{
    IBOutlet NSTextField *textField;
}
- (IBAction)generate:(id)sender;
- (IBAction)seed:(id)sender;
@end

The #import statement is basically a #include that avoids the recursive effects of including a file that includes you.

The @interface statement declares the Foo class as a subclass of NSObject. There is a single instance variable, textField. Instance variables are declared inside the curly braces, Methods are declared after the curly braces and before the @end statement.

You don't need to change a line of this code. Interface Builder did all the work for you. Let's edit Foo.m, where the real action is. Here's what Foo.m looks like before you change it:

#import "Foo.h"
@implementation Foo
- (IBAction)generate:(id)sender
{
}
- (IBAction)seed:(id)sender
{
}
@end

Here's the edited version:

#import "Foo.h"
@implementation Foo
- (IBAction)generate:(id)sender
{
   int generated;
   
   generated = (random() % 100) + 1;
   
   [textField setIntValue:generated];
}
- (IBAction)seed:(id)sender
{
   srandom( time( NULL ) );
   [textField setStringValue:@"Generator seeded"];
}
- (void)awakeFromNib
{
   [textField setStringValue:@"Seed the Generator!!!"];
}
@end

Basically, you are adding 3 lines to the generate: method, 2 lines to the seed: method, and the 4 lines that make up the awakeFromNib: method. I added awakeFromNib: so the text field would have a reasonable setting at startup.

Don't worry too much about the code itself. The key here is that with 9 pretty simple lines of code and some time invested in Interface Builder, we've created a running application that does something interesting.

Build and run the application by selecting Build and Run from the Build menu. Figure 12 shows RandomApp when it starts up. Click the Seed Generator button, then click Generate Random Number to start generating random numbers. Hey, it works!


Figure 12. RandomApp in action.

Some Ramblings Before I Go

Some unrelated blathering before I leave. Sort of a static blog, if you will.

Deneen and I just got a Prius. To me, this is the car of the future. Today. I really, really love this car. It is a hybrid vehicle with a gas engine and an electric motor. The Prius switches between the two as needed. Gets extremely high gas mileage and has very low emissions. Worth checking out.

If you get a sec, go to http://www.spiderworks.com and check out my new project. It consumes me.

Also, I want to stand up on my chair and applaud O'Reilly for publishing Wil Wheaton's short story collection, Dancing Barefoot. I love that they did this. Wil Wheaton is an actor, played Wesley Crusher in a past life and, most importantly, has an exceptionally entertaining web site:

http://www.wilwheaton.net

Check out the site, check out the book.

Oh Yeah - WWDC is Just Around the Corner

Can you believe it? WWDC is just a couple of months away. Just like last year, this year's Worldwide Developers Conference will be in San Francisco from June 28th through July 2nd. Apple has reported that they have close to 10 million active Mac OS X users and over 10,000 native Mac OS X applications. These numbers show incredible adoption growth since last year's conference and that's good news for developers.

This year's conference offers 7 tracks: Application Technologies, Development Tools, Enterprise IT, Graphics and Media, Hardware Technologies, OS Foundations, and QuickTime Digital Media. Look for the QuickTime track to mix in integration of Pro Apps (DVD Studio Pro, for example) and to cover creation of audio loops for Soundtrack, GarageBand, Logic, etc. This one is definitely on my short list!

Read all about the conference here:

http://developer.apple.com/wwdc/features.html

Note that there is a discount if you buy your ticket by April 30th.

Till Next Month...

I am having a great time writing about Cocoa. Expect this nonsense to continue. If you insist on homework, find the Property List Editor (/Developer/Applications/Utilities/) and use it to open (a copy of) your .nib file. Fascinating.

See you in the future...


Dave Mark is a long-time Mac developer and author and has written a number of books on Macintosh development, including Learn C on the Macintosh, Learn C++ on the Macintosh, and The Macintosh Programming Primer series. Dave's been busy lately cooking up his next concoction. Want a peek? http://www.spiderworks.com.

 

Community Search:
MacTech Search:

Software Updates via MacUpdate

SpamSieve 2.9.38 - Robust spam filter fo...
SpamSieve is a robust spam filter for major email clients that uses powerful Bayesian spam filtering. SpamSieve understands what your spam looks like in order to block it all, but also learns what... Read more
TeamViewer 15.0.8397 - Establish remote...
TeamViewer gives you remote control of any computer or Mac over the Internet within seconds or can be used for online meetings. Find out why more than 200 million users trust TeamViewer! Free for non... Read more
SteerMouse 5.4.3 - Powerful third-party...
SteerMouse is an advanced driver for USB and Bluetooth mice. SteerMouse can assign various functions to buttons that Apple's software does not allow, including double-clicks, modifier clicks,... Read more
Toast Titanium 18.2.1 - The ultimate med...
Roxio Toast Titanium, the leading DVD burner for Mac, makes burning even better, adding Roxio Secure Burn to protect your files on disc and USB in Mac- or Windows-compatible formats. Get more style... Read more
HoudahSpot 5.0.11 - Advanced file-search...
HoudahSpot is a versatile desktop search tool. Use HoudahSpot to locate hard-to-find files and keep frequently used files within reach. HoudahSpot will immediately feel familiar. It works just the... Read more
ClipGrab 3.8.6 - Download videos from Yo...
ClipGrab is a free downloader and converter for YouTube, Vimeo, Facebook and many other online video sites. It converts downloaded videos to MPEG4, MP3 or other formats in just one easy step Version... Read more
ExpanDrive 7.4.0 - Access cloud storage...
ExpanDrive builds cloud storage in every application, acts just like a USB drive plugged into your Mac. With ExpanDrive, you can securely access any remote file server directly from the Finder or... Read more
Adobe Dreamweaver CC 2020 20.0 - Build w...
Dreamweaver CC 2020 is available as part of Adobe Creative Cloud for as little as $20.99/month (or $9.99/month if you're a previous Dreamweaver customer). Adobe Dreamweaver CC 2020 allows you to... Read more
Eye Candy 7.2.3.85 - 30 professional Pho...
Eye Candy renders realistic effects that are difficult or impossible to achieve in Photoshop alone, such as Fire, Chrome, and the new Lightning. Effects like Animal Fur, Smoke, and Reptile Skin are... Read more
Sparkle Pro 2.8.5 - Visual website creat...
Sparkle Pro will change your mind if you thought building websites wasn't for you. Sparkle is the intuitive site builder that lets you create sites for your online portfolio, team or band pages, or... Read more

Latest Forum Discussions

See All

Pre-register for Hello Kitty AR: Kawaii...
Hello Kitty — the cute cat that launched a multi-billion-pound franchise — has been brought to life… sort of. Sanrio has teamed up with the Bublar Group to create a new mobile game that uses AR tech to turn the real world into Hello Kitty’s... | Read more »
Gorgeous and tranquil puzzler Spring Fal...
One-man indie studio SPARSE//GameDev has now launched its tranquil puzzler, Spring Falls. It's described as "a peaceful puzzle game about water, erosion, and watching things grow". [Read more] | Read more »
Black Desert Mobile gets an official rel...
Pearl Abyss has just announced that its highly-anticipated MMO, Black Desert Mobile, will launch globally for iOS and Android on December 11th. [Read more] | Read more »
Another Eden receives new a episode, cha...
Another Eden, WFS' popular RPG, has received another update that brings new story content to the game alongside a few new heroes to discover. [Read more] | Read more »
Overdox guide - Tips and tricks for begi...
Overdox is a clever battle royale that changes things up by adding MOBA mechanics and melee combat to the mix. This new hybrid game can be quite a bit to take in at first, so we’ve put together a list of tips to help you get a leg up on the... | Read more »
Roterra Extreme - Great Escape is a pers...
Roterra Extreme – Great Escape has been described by developers Dig-It Games as a mini-sequel to their acclaimed title Roterra: Flip the Fairytale. It continues that game's tradition of messing with which way is up, tasking you with solving... | Read more »
Hearthstone: Battlegrounds open beta lau...
Remember earlier this year when auto battlers were the latest hotness? We had Auto Chess, DOTA Underlords, Chess Rush, and more all gunning for our attention. They all had their own reasons to play, but, at least from where I'm standing, most... | Read more »
The House of Da Vinci 2 gets a new gamep...
The House of Da Vinci launched all the way back in 2017. Now, developer Blue Brain Games is gearing up to deliver a second dose of The Room-inspired puzzling. Some fresh details have now emerged, alongside the game's first official trailer. [Read... | Read more »
Shoot 'em up action awaits in Battl...
BattleBrew Productions has just introduced another entry into its award winning, barrelpunk inspired, BattleSky Brigade series. Whilst its previous title BattleSky Brigade TapTap provided fans with idle town building gameplay, this time the... | Read more »
Arcade classic R-Type Dimensions EX blas...
If you're a long time fan of shmups and have been looking for something to play lately, Tozai Games may have just released an ideal game for you on iOS. R-Type Dimensions EX brings the first R-Type and its sequel to iOS devices. [Read more] | Read more »

Price Scanner via MacPrices.net

13″ 2.4GHz MacBook Pros available for up to $...
Apple has a full line of Certified Refurbished 2019 13″ 2.4GHz 4-Core Touch Bar MacBook Pros available starting at $1529 and up to $300 off MSRP. Apple’s one-year warranty is included, shipping is... Read more
New at T-Mobile: Switch to T-Mobile, and get...
T-Mobile is offering a free 64GB iPhone 8 for new customers who switch to T-Mobile and open a new line of service. Eligible trade-in required, and discount applied over a 24 month period. The fine... Read more
Xfinity Mobile’s Black Friday Apple savings:...
Take $250 off the purchase of any iPhone at Xfinity Mobile with a new line activation, and transfer of phone number to Xfinity Mobile, through December 8, 2019. This includes Apple’s new iPhone 11... Read more
2019 13″ 1.4GHz MacBook Pros available starti...
Apple has a full line of Certified Refurbished 2019 13″ 1.4GHz 4-Core Touch Bar MacBook Pros available starting at $1099 and up to $230 off MSRP. Apple’s one-year warranty is included, shipping is... Read more
Save up to $350 on a 21″ or 27″ iMac with the...
Apple has Certified Refurbished 2019 21″ & 27″ iMacs available starting at $929 and up to $350 off the cost of new models. Apple’s one-year warranty is standard, shipping is free, and each iMac... Read more
Early Holiday 2019 Sale: B&H again offers...
B&H Photo has 10.2″ iPads on sale again for $30 off Apple’s MSRP, starting at $299, as part of their early Holiday 2019 sale. Overnight shipping is free to many addresses in the US: – 10.2″ 32GB... Read more
Apple iMacs on sale today at B&H Photo fo...
B&H Photo has new 2019 21″ and 27″ 5K iMacs on stock today and on sale for up to $150 off Apple’s MSRP. Overnight shipping is free to many locations in the US. These are the same iMacs sold by... Read more
2018 4 and 6-Core Mac minis on sale today for...
Apple resellers are offering new 2018 4-Core and 6-Core Mac minis for $80-$100 off MSRP for a limited time. B&H Photo has the new 2018 4-Core and 6-Core Mac minis on sale for up to $100 off Apple... Read more
Early Holiday 2019 sale at B&H Photo: 12....
B&H Photo has new 12.9″ iPad Pros on sale for up to $120 off Apple’s MSRP as part of their early Holiday 2019 sale. Overnight shipping is free to many addresses in the US: – 12.9″ 64GB WiFi iPad... Read more
8-Core iMac Pro on sale today for $4499 at B...
B&H Photo has the base 8-Core 3.2GHz 32GB/1TB iMac Pro on sale today for $4499 — $500 off Apple’s MSRP. Shipping is free. Their price is the lowest available for a new iMac Pro from any Apple... Read more

Jobs Board

*Apple* Health Benefit Specialist - Call Cen...
Description ** Apple Health Benefit Specialist - Call Center (MAS 3/MACSC)** **Olympia, WA Multiple Positions** *The ideal candidate for this position will have Read more
Hair Stylist - *Apple* Blossom Mall - JCPen...
Hair Stylist - Apple Blossom Mall Location:Winchester, VA, United States- Apple Blossom Mall 1850 Apple Blossom Dr Job ID:1065040Salon Professionals Job Read more
*Apple* Mobility Pro - Best Buy (United Stat...
**747088BR** **Job Title:** Apple Mobility Pro **Job Category:** Store Associates **Store NUmber or Department:** 000297-Reston-Store **Job Description:** At Best Read more
Nurse Practitioner - Field Based (San Bernard...
Nurse Practitioner - Field Based (San Bernardino, CA, Apple Valley, Hesperia) **Location:** **United States** **Requisition #:** PS30312 **Post Date:** Nov 11, 2019 Read more
Best Buy *Apple* Computing Master - Best Bu...
**747061BR** **Job Title:** Best Buy Apple Computing Master **Job Category:** Store Associates **Store NUmber or Department:** 000647-Kildeer-Store **Job Read more
All contents are Copyright 1984-2011 by Xplain Corporation. All rights reserved. Theme designed by Icreon.