Long Pointers

Matt Long’s Blog About Programming and Stuff

XCode 3.0 Tutorial

Filed under: Apple Computer, Cocoa/Objective-C, Engineering Journal, Programming — perlmunger at 2:30 pm on Friday, November 9, 2007


I’ve seen numerous posts on different discussion boards posted by new Mac users wanting to learn to write code for the Mac. The main complaint is that Interface Builder is too different from the existing documentation, including Aaron Hillegass’s excellent Cocoa Programming for Mac OS X (which actually remains very relevant, by the way. You can wait for some updated books to come out, but Aaron’s book still provides a lot of concepts and even methods that apply. You just need to know what’s changed in XCode 3 and Objective-C 2). So, I’m going to do a quick tutorial here. FULL DISCLOSURE: I learned this from Marcus Zarra, so credit where credit is due. ;-)

Here are some points that you should keep in mind before moving ahead:

  • Don’t use Interface Builder to generate code. Create your code in XCode and let Interface Builder work with it. This isn’t absolutely necessary, but as Marcus told me, it’s just easier to get in this habit as the XCode 2 method of creating your controller, instantiating it, and generating your code files from Interface Builder simply isn’t available in the same way in XCode 3.0. I’ve come to see what Marcus is saying. It makes sense, but you’ll have to get into the process yourself to fully understand it. We’ll get to that in a minute.
  • Understanding Cocoa programming is much simpler if you learn MVC. You can probably step through code examples and figure some things out without learning MVC (Model, View, Controller), but I wouldn’t recommend it. Go Google it and read up on it.

    I will say as an introduction to it for those who are not familiar that it should probably be called (Model <--> Controller <--> View) or (View <--> Controller <--> Model) as the controller always sits between the other two. Your controller is either telling your model to update its data or it is telling the view to update its display. That’s the crux of the whole paradigm. The details run much deeper, but that’s how I would nutshell it for you.

Create Your Application

Let’s get started. Create a Cocoa Application using the following steps:

  1. Select File > New Project… and choose Cocoa Application in the ensuing dialog. Click Next
  2. Enter ‘FirstApp’ as the project name. Click Finish

You should see a project workspace like the following:
FirstApp Workspace

The next thing you should do is create a class to act as your controller or delegate.

Delegate == Controller

The words delegate and controller can be used synonymously. You’ll see later that we delegate the work of the different controls we create in Interface Builder to a delegate or controller class. This should all make perfect sense momentarily. First, create your controller/delegate class using the following steps:

  1. Option-Click on the Classes folder in your workspace and select ‘Add File…’
    Add File
  2. Choose Object-C Class in the ensuing dialog and click Next
    New File Dialog
  3. Name the file ‘AppDelegate.m’ and click Finish
    New Objectiv-C Class
  4. A new code window will display with your ‘AppDelegate’ interface code (.h file). Add an outlet for a text field and a label, and an action to the code so that it looks like this:
    C:
    1. @interface AppDelegate : NSObject {
    2.     IBOutlet NSTextField *textField;
    3.     IBOutlet NSTextField *label;
    4. }
    5. - (IBAction)clickButton:(id)sender;
    6. @end

  5. Now switch over to your implementation file for ‘AppDelegate’ (.m file). Add the clickButton implementation code so that the file looks like this:
    C:
    1. @implementation AppDelegate
    2.  
    3. - (void)clickButton:(id)sender;
    4. {
    5.    
    6. }
    7.  
    8. @end

    We will actually add some code to do something in the clickButton handler, but first we need to hook it up to the user interface in Interface Builder.

Interface Builder And Controller/Delegate Implementation

Now that you’ve specified the outlets–two NSTextFields, one a text field and one a label in this case–and an action called clickButton, you will see these items available for connecting to the UI in Interface builder. Let’s open Interface Builder and make the connections we need using the following steps:

  1. In your XCode workspace, expand the folder in the tree view called NIB Files and double click the file called ‘MainMenu.nib’. This will open the nib file in Interface Builder
    Select NIB File in Workspace
  2. Once Interface Builder loads select the NSObject item and drag it into the ‘MainMenu.nib’ window.
    Add NSObject
    Then rename it to ‘AppDelegate’
    Interface Builder AppDelegate

Making Connections (Pay Attention Here)

These next two steps are critical for your understanding. You now need to tell Interface Builder the following:

  • What object you want to use as a File’s Owner. You will delegate actions to a delegate/controller object. You tell the application which object to use by setting the File’s Owner delegate.
  • What type of object this delegate is. Before you can specify which object to use as the File’s Owner you have to set the object type. A regular NSObject doesn’t provide any implementation for your app. You need to tell Interface Builder that you want your NSOBject to actually be an object of type ‘AppDelegate’.

You can achieve this by completing the following steps:

  1. If you haven’t already, open the Inspector in Interface Builder by selecting Tools > Inspector
  2. Click on your NSObject that you named ‘AppDelegate’ and then click on the Identity tab in the inspector.
  3. Change the class to type ‘AppDelegate’ which will be available in Interface Builder as it has been able to obtain the class information from XCode.
    Set Delegate Class

    You should also notice at this point in the Class Actions and Class Outlets sections of the Inspector, your action, clickButton: and your outlet, the NSTextField are now visible. We’ll hook those up in just a minute.

  4. Control-Click the File’s Owner object in the ‘MainMenu.nib’ window and drag it to the ‘AppDelegate’ object.
    Set File's Owner

    A pop-up list will display. Select delegate.
    Set File's Owner Delegate

Design The User Interface

Now you simply need to add the controls to the main window in Interface Builder and then we can connect the action and outlet accordingly. To finish the interface, complete the following steps:

  1. Drag a TextField, a Label, and a Button to the main window so that the user interface looks like the screenshot below:
    Application Main Window Design
  2. Control-Click and drag from the Buttonto your ‘AppDelegate’ object in the ‘MainMenu.nib’ window.
    Set Button Delegate
    A pop-up will display. Select clickButton:
    Set Button Action
  3. Control-Click the ‘AppDelegate’ object and drag it to the text field in the main form.
    Connect Text Field
    A pop-up will display. Select textField
    Select Text Field
  4. Control-Click the ‘AppDelegate’ object and drag it to the label in the main form.
    Connect Label

    A pop-up will display. Select label
    Select Label

That’s it for Interface Builder. You can quit interface builder and return to XCode. We have one more piece of code to add and then our application will be finished.

Finishing Up

When the button is clicked, it will simply grab the text from the text field and place it into the label. That’s all the application does. Here’s the code you need. Just make your implementation in the ‘AppDelegate.m’ file look like this:

C:
  1. @implementation AppDelegate
  2.  
  3. - (void)clickButton:(id)sender;
  4. {
  5.     NSString *text = [textField stringValue];
  6.     [label setStringValue:text];
  7. }
  8.  
  9. @end

Now all you need to do is click “Build and Go”. When the application runs, type some text into the text field and click the button. You will see the label update with the text from the text field.

When I originally tried to build this application, I had to get Marcus’ help. Then he showed me a great way to have the label update in real time as you type text into the text field. It was accomplished using the new @synthesize method in Objective-C 2.0. I won’t go into the details of that now, but needless to say there are a lot of different ways to achieve what you want for your app.

Further Discussion

It has been most helpful for me while learning to write code for the Mac that from an interface standpoint, there are two entities that you need to be concerned with–actions and outlets. Outlets are normally UI controls such as text fields, list boxes, and buttons while actions are, well, actions–the action you want to happen when some event from a control is triggered.

If you connect all of your outlets to their declarations in your controller/delegate code implementation, you don’t have to do any control object instantiation in code. There may be times when this is desirable, however, most of the time you can just connect and go. Just use your controls as all of the instantiation/initialization is handled for you by the framework.


You can download the xCode project here: FirstApp Demo Application



29 Comments »

Comment by sabeau

November 17, 2007 @ 12:48 am

Hey matey, thanks for taking the time to put this together, I’ve been struggling to get into OS X development using cocoa as I’m a java EE developer for my day job. This has really helped me break through the wall, cheers.

Comment by perlmunger

November 17, 2007 @ 11:10 am

Glad it was helpful.

-Matt

Comment by HenryMagician

November 21, 2007 @ 1:01 pm

In interface builder, I can’t change the name of the new object. I tried doing it without changing the name, and it worked fine. The problem is, when I tried to test the App. it came up with an error. I clicked on what the error was, and it says

error: There is no SDK at specified SDKROOT path ‘/Developer/SDKs/MacOSX10.5.sdk’

PLEASE HELP! Thanks in advance.

Henry

Comment by HenryMagician

November 21, 2007 @ 1:04 pm

I did it all, except for changing the name of the Object, which I couldnt figure out how to do.

I get an error message when I try to build and go though. Says

error: There is no SDK at specified SDKROOT path ‘/Developer/SDKs/MacOSX10.5.sdk’

PLEASE HELP!

Thanks in advance,
Henry

Comment by perlmunger

November 21, 2007 @ 2:28 pm

Henry, it sounds to me like your SDK got deleted. Open the finder and navigate to /Developer/SDKs/ and see if the SDK ‘MacOSX10.5.sdk’ is in fact there. If not, then I suggest you just re-install the dev tools. Actually, you may try that either way. Let me know.

-Matt

Comment by mlue

November 25, 2007 @ 1:46 am

Thanks alot for this, Hillegaas’s book is a bit hard to reconcile.

Comment by Geeklawyer

December 26, 2007 @ 3:58 pm

Oh Lord, Matthew. Thanks for this. I thought I was going fric*ing mad. I was wondering why all me ‘Hello World’ example programs didn’t work.

You made it clear Apple broke everything in Xcode3 - yea maybe with good reason, but where are all the help/tutorial updates in Xcode? These all relate to Xcode 2; they are still in there and *I* cannot find anything that relates to Xcode3 * the InterfaceBuilder changes in the tutorials.

I hope I’m wrong (please show me why!! ) but I fear not, This is criminal and demonstrates how Leopard & related tools have been rushed out unfinished. Thanks a lot iPhone.

Comment by perlmunger

December 26, 2007 @ 4:29 pm

Glad it helped, Geeklawyer. I agree that it seems most tutorials have not yet been updated. I just saw the other day that one of the Cocoa Dev Central tutorials has recently been updated, though. You can see it here: http://cocoadevcentral.com/d/learn_cocoa/

Pingback by GeekLawyer’s Blog » Geek rant (tune out, lawyers)

December 27, 2007 @ 7:25 am

[...] one has to drag in a new NSobject from the library, rename it and then start to play. Mercifully Matthew Long explained this. It’d be nicer if Apple had bothered but Geeklawyer guesses it was too busy counting iPhone [...]

Comment by keithljelp

December 27, 2007 @ 10:38 am

An outstanding introduction to programming applications. It was just what I needed to get started.

Comment by nender

December 28, 2007 @ 8:00 pm

I’ve been having a weird issue, in step 3 of making connections, I get no outlets. So later when I try to connect the button to AppDelegate, it won’t let me. I’ve tried a few times and gone through the code but no luck. Any help? A link to a confirmed good .h file would be great.

Comment by perlmunger

December 28, 2007 @ 8:24 pm

Nender,

I’m not sure what problem you’re having, so I’ve uploaded my entire xCode project. You can download it here.

-Matt

Comment by nender

December 28, 2007 @ 10:46 pm

Thanks a bunch Matt, that solved my problem.

Comment by jag

February 2, 2008 @ 12:56 am

Thanks for the intro!

I too was stymied from renaming the new object. I tried double-clicking the name (ding), using the Finder trick of pressing return (ding), control-clicking the name (no ding, but no rename option), checking the menus — nothing. I even tried searching via Help, but it found only the Finder rename.

Finally, what worked was first selecting the object (it was already selected after dragging it over, but by now I’ve clicked all over creation), then clicking ONCE on the name and waiting (oh so patiently) for a second or two.

Do you know any way of avoiding that second-or-two delay?

Thanks again for taking the time to write this up, Matt!

Comment by perlmunger

February 2, 2008 @ 8:57 am

@Jag

I’ve looked for a quicker way and I’m pretty sure you’re stuck with the delay. I don’t think it’s even a full second, though. I click the icon. Then click the text and it’s editable within a second.

Best Regards.

-Matt

Pingback by links for 2008-02-07 « Ramblings of an Eccentric Soul…

February 7, 2008 @ 12:22 pm

[...] Xcode 3.0 Tutorial (tags: xcode programming mac osx leopard) « links for 2008-02-05 [...]

Comment by patrickparker

February 8, 2008 @ 11:51 am

I simply can not seem to rename the new object.

“Finally, what worked was first selecting the object (it was already selected after dragging it over, but by now I’ve clicked all over creation), then clicking ONCE on the name and waiting (oh so patiently) for a second or two.”

The above does not work for me. I’m using Version 3.0 (629). Is this a bug?

Comment by perlmunger

February 8, 2008 @ 12:04 pm

Hey PATRICKPARKER

Not sure what the problem is. In IB, click once on the controller object you dragged into the Nib so that it is selected like this.

Wait a second and then click the text under the icon. Wait another second. It should become editable. If not, then I’m not sure. Try restarting IB and do the same thing again. Let me know how it goes.

-Matt

Pingback by Kuma’s Lair » Blog Archive » Good Cocoa Programming Blog Entry…

February 8, 2008 @ 12:58 pm

[...] Long Pointers » XCode 3.0 Tutorial [...]

Comment by Johnjohn7188

February 9, 2008 @ 4:00 pm

Finally! Thank you so much for this tutorial. I’ve been developing applications in Visual Studio for a while now but couldn’t figure out how to use XCode! Thanks again!

Comment by perlmunger

February 9, 2008 @ 4:35 pm

Hey John. Glad it was helpful.

-Matt

Pingback by Cocoa: Learning with updated tools » señor taco’s travels

February 10, 2008 @ 4:09 pm

[...] to Leopard2. It’s been good and challenging, but nothing unbearable. Today I ran across documentation on the changes to Leopard one needs to know to use the book. Sweet! Footnotes:OS X 10.4↩OS X [...]

Pingback by Long Pointers » Windows Programmers Shifting to the Mac?

February 29, 2008 @ 2:32 pm

[...] get a Mac and start coding. It’s that easy. And if you need some pointers, take a look at my XCode 3.0 article to get your started. When you’re done with that, head on over to Cocoa Dev Central for some [...]

Pingback by Time to Learn Objective-C « Dead Ink Vinyl

March 10, 2008 @ 8:26 am

[...] instructions into Xcode 3 operations, but it was all too new to me. Fortunately, Matt Long has an excellent tutorial filled in the gaps sufficiently for me to progress further. However Matt Long’s solution [...]

Pingback by Dinu’s House » XCode 3.0 Tutorial

March 11, 2008 @ 9:36 pm

[...] Add an outlet for a text field and a label, and an action to the code so that it looks like this: PLAIN TEXT [...]

Comment by AaronD12

March 15, 2008 @ 8:33 am

Thank you for writing this. However, I’ve found a couple of errors in your article while going through it step-by-step:

1. Under “Delegate == Controller”, step 1 should read “Control-click (or right-click) the classes folder and select Add… > New File.”

2. Under the “Making Connections” section, step 3, the clickButton: and label and textField do NOT appear unless you saved your project in XCode. While Interface Builder is open, you can save your project then these items appear.

3. You might want to mention in step 1 of “Design the User Interface” to drag the label’s handles to the width of the text box. It took me a moment to realize this when my application would only show the first 5 characters I entered into the text box.

All things said, this is a great “hello world” application! Apple’s “hello world” is still in XCode 2 mode. I found it impossible to follow using XCode 3. Thanks again for posting this!

Pingback by XCode and Objective-C from Visual Studio and C# | The Diary

March 17, 2008 @ 3:37 pm

[...] also been having a go with a simple XCode 3.0 Tutorial that I found while browsing the web. It helpfully showed me that stripping the PPC binaries from my [...]

Pingback by chrome's cocoa coding calisthenics! exercise 1 - MacTalk Forums

April 3, 2008 @ 3:18 am

[...] should resize with the window correctly. The menu is not important at this stage. Hints. Read Long Pointers XCode 3.0 Tutorial This tutorial gives you an application similar to what we’re after, however it will require small [...]

Pingback by links for 2008-05-09 « copula’s weblog

May 9, 2008 @ 2:39 am

[...] Long Pointers » XCode 3.0 Tutorial (tags: mac development programming tutorial) [...]

RSS feed for comments on this post. TrackBack URI

Leave a comment

You must be logged in to post a comment.