Your First iPhone App - Learning iPhone Programming (2010)

Learning iPhone Programming (2010)

Chapter 3. Your First iPhone App

In this chapter, you’ll build a small Hello World application and run it in iPhone Simulator. If you’re enrolled in the iPhone Developer Program, you’ll even get to run the application on your iPhone or iPod touch. I’m going to take you through this step by step, just to give you an idea of how Xcode and Interface Builder work together.

Note

Enrolling in the iPhone Developer Program is separate from registering as an iPhone developer. Enrollment ($99 or $299 per year, depending on which program you join) provides you with the software certificates and online provisioning tools needed to run your own apps on your own iPhone and submit them for approval to the App Store.

However, even if you don’t plan to enroll in a Developer Program, you will need to register so that you can download the iPhone SDK needed to create apps. See Chapter 2 for more information on registering and enrolling.

Objective-C Basics

I talk in detail about how Objective-C applications are normally structured in Chapter 4. However, in this chapter, although I do get into Objective-C’s sometimes quirky syntax, I’m going to give you a higher-level overview of the language to get you going quickly.

Object-Oriented Programming

If you’ve heard someone explain object orientation before, the distinction between the terms class and object may not be totally clear. However, there is a difference. A class is the blueprint for objects; each time you create an object, the class definition determines its structure. An object is a collection of operations (methods) and information (data) that occupies space in memory and can be instructed to perform operations (invoke methods) on that information.

For those of you who are new to programming, the following list defines some of the terms you’ll come across frequently:

Objects and classes

A class consists primarily of two things: variables that can store data and methods that can perform operations. The methods are used to retrieve, set, and manipulate the variables. Objects—sometimes referred to as instances of a class—have specific values associated with these variables. For example, you might use Apple’s UIViewController class to manage the view (i.e., UI) you present to the user of your application. You also might create an instance of that class named myViewController to actually carry out the work of managing the view presented to the user. This would then be referred to as the myViewController object. An instance of a class should not be confused with its implementation, which is the realization of the class in code.

Subclasses

Classes can also inherit functionality from an existing class (the parent or base classes, commonly known as the superclass); classes that inherit functionality in this way are referred to as subclasses. This means you can invoke a method of the parent class on an object that is an instance of a subclass of the parent. Subclassing is normally done so that you can extend the functionality of that class with additional methods or data. For example, when writing applications for the iPhone you commonly define a subclass of the UIViewController class to manage your views, instead of using the class directly. The subclass of the standard view controller inherits all of the properties of its parent class, but in addition it allows you to implement code to handle the specific view presented to the user, such as data entry and validation.

Instance and class variables

Both instance and class variables are defined as part of the class declaration. However, every object (instance of the class) holds a separate copy of an instance variable. In other words, if a class defines a variable foo, the value of foo can be different for objects for the same class. Changing the value of an instance variable in one object will not affect the value of the same variable in all the other objects of that class. Conversely, only a single copy of a class variable exists. If you change the value of a class variable from one object, the value of that variable will change for all the objects of that class.

Accessor methods

Accessor methods, sometimes called getters and setters, are usually fairly simple methods used to get and set instance variables in a class. They are used to provide an abstraction layer between variables and the outside world so that the implementation of the class can change without having to change any code outside of the class itself. In Objective-C, the compiler can generate these commonly used functions for you.

Class methods

Class methods (also known as static methods) are similar in nature to class variables. These are methods that are associated directly with the class rather than the object instance; they therefore will not have access to object instance variables.

Events and messages

An event is a message generated by the user interacting with your application’s controls. For instance, if you tap the screen of your iPhone or iPod touch, this generates a UI event in your application that is passed via a message from the application to an object that has been delegated to deal with that specific type of event.

Protocols

A protocol definition declares methods that any class can implement. If your class declares that it abides by a particular protocol definition, you are announcing that you have implemented the minimum mandatory methods declared in the protocol definition, and may optionally have implemented some nonmandatory methods.

Delegate classes

A delegate class is a class that implements a protocol for handling events. Each delegate protocol specifies a number of methods that must be implemented, and additionally methods that may optionally be implemented. Declaring your class a delegate implies that it (at least) implements the mandatory methods. For instance, if your UI has a button, you can declare your class a delegate to handle events generated by the button.

Event loop

The main event loop is the principal control loop for your application. This loop is the process that receives and then passes external events, such as the user tapping the iPhone’s screen or changes in the device’s orientation, to the appropriate delegate classes that you’ve included in your application.

Frameworks and libraries

A framework is a collection of related classes, protocols, and functions collected together within a cohesive architecture. When you make use of a framework many of the design decisions about how you as a developer will use the code it includes have been taken out of your hands. However, by using the standard frameworks, you inherit standard behavior. For example, when Apple introduced Copy & Paste to the iPhone with the release of version 3.0 of the firmware, it was enabled by default in most third-party applications because the developers made use of the standard UIKit framework to build those applications.

The Objective-C Object Model

For those of you coming from an object-oriented background, there are a number of differences between the Objective-C model of object orientation and the one implemented by Simula-derived languages such as C++, Java, and C#.

While its nonobject operations are identical to C, Objective-C derives its object syntax almost directly from the Smalltalk language. Its object model is based on sending messages to object instances; in Objective-C you do not invoke a method, but instead send a message. What’s the difference? Invoking a method implies that you know something about that method. Sending a message leaves it up to the receiver of the message to figure out what to do with it.

This kind of loosely coupled chain of command means that Objective-C is much more dynamic at runtime than the Simula-derived languages, but it also means it might appear to be insubordinate.

That’s because in Simula-derived languages, you must know the type of an object before you can call a method on it. In Objective-C this is not the case. You simply send the object a message. The receiving object then attempts to interpret the message, but there is no guarantee of a response. If it doesn’t understand the message, it will ignore it and return nil. Among other things, this kind of model does away with the need to continually cast objects between types to ensure that you are sending a message that will be understood.

Note

Casting is the process whereby you represent one variable as a variable of another type. This is done both for primitive types (suppose you want to change a float to an integer as part of an integer arithmetic operation), as well as for objects. An object can be cast to another object type if it is a subclass of that type. In Objective-C, objects can be represented by the generic id type, and you can cast objects to this type without regard for their parent class.

The other main difference is in the way memory is managed. While languages such as Java use garbage collection to handle memory management, in Objective-C memory is managed using reference counting (the alloc-retain-release cycle, as discussed in Chapter 4).

Garbage Collection and Reference Counting

In the simplest case, memory management must provide a way to allocate a portion of memory and then free that memory when it is no longer needed. Garbage collection is a form of memory management that automatically attempts to free memory that is no longer in use. While garbage collection frees the developer from having to worry about manually managing memory, the point where memory is automatically freed can be unpredictable, and the garbage collection routines consume additional computing resources.

Reference counting is a form of garbage collection, which counts the number of references to an object (or portion of memory) and frees the associated memory when the number of references reaches zero. The main advantage of reference counting over “classic” garbage collection is that memory is freed as soon as it is no longer in use. Although most programmers wouldn’t necessarily class it as such, reference counting is among the simplest garbage collection algorithms, as it frees the developer from having to manually manage memory at a low level.

Finally, the applications are almost invariably based on the Model-View-Controller (MVC) (design) pattern, which is pervasive in the Cocoa Touch and other frameworks that you’ll use to build iPhone applications. Rather than encouraging you to create subclasses, the MVC pattern makes use of delegate classes. A pattern is a reusable solution to a commonly occurring problem; in object-oriented programming, patterns usually describe how the developer should model the application in terms of the classes that are used, and how the developer should structure the interactions and relationships between these classes.

For example, the root UIApplication class implements the behavior necessary for an application, but instead of forcing you to subclass the UIApplication class for your own application and add your own code to the subclass, it delivers notification messages of events to an assigned delegate class that implements the UIApplicationDelegate protocol. The UIApplication class asks the delegate class to respond to events when they occur.

The Basics of Objective-C Syntax

I’ll dive a bit deeper into Objective-C as we go through the book, but to make it through this chapter all you really need to know is that while variable declarations look much the same as variable declarations do in other languages, method calls are surrounded by square brackets. So, for example, both of the following lines of code are method calls:

[anObject someMethod];1

[anObject someMethod: anotherObject];2

1

The someMethod message is sent to the anObject object.

2

The someMethod message is sent to the anObject object and passes anotherObject as an argument.

Despite the sometimes quirky syntax (including the square brackets and colon shown in the preceding code) that Objective-C has inherited from Smalltalk, the logic of what is going on should be clear, and we’ll discuss the syntax in much greater detail in the next chapter.

Creating a Project

Now let’s create our first application in Xcode. Launch Xcode by double-clicking its icon (it’s located in the /Developer/Applications folder on your hard drive). Click “Create a new Xcode project” in the Xcode welcome window, and then click Application under the iPhone OS section on the left side of the screen. Next, click the View-based Application template and click Choose. When prompted, name your new project HelloWorld. Make sure you don’t put a space between Hello and World, as this can sometimes confuse Xcode.

Note

If you don’t see a welcome window when you start up Xcode, you can create a new project by choosing File→New Project.

Xcode will now open a project window. The left pane shows the classes and other files associated with the project, organized into groups. If you double-click on each group icon, the group will expand to show you the files it contains, as shown in Figure 3-1. The application template you choose determines how the groups are arranged, but you can move the files around and create your own groups if you prefer to organize things differently. The two main groups you’ll be working with are Classes, which contain all the classes that make up the application, and Resources, which contain other supporting files, including the .xib files that the Interface Builder application uses to describe your application’s UI. By default, the project will open to the top level of the project hierarchy, and the top-right pane will show a list of all the files associated with the project. The bottom-right pane (blank at first) will show you the source code of whichever file you have clicked on.

The initial project window opened by Xcode

Figure 3-1. The initial project window opened by Xcode

Exploring the Project in Xcode

When you created the project, Xcode generated a number of files and, along with them, a lot of the boilerplate code you’d otherwise have to laboriously type in. In fact, the project that Xcode generates for you is a complete (if boring) iPhone application. You know those flashlight applications that have proliferated on the App Store? You’ve just written one....

If you click the Build and Run button in the Xcode toolbar (see Figure 3-1), Xcode will compile the application, deploy it in iPhone Simulator, and then run it. After the application opens, what you see in the simulator should look very similar to Figure 3-2, a simple, blank, gray view.

Our Xcode template compiled and running inside iPhone Simulator

Figure 3-2. Our Xcode template compiled and running inside iPhone Simulator

Let’s look at the files Xcode has generated as part of the template and how it has divided them into separate groups in the Groups & Files pane of the interface:

Classes

The Classes group contains the classes and header files we’re most interested in and will be working with in this chapter. These are HelloWorldAppDelegate.h, HelloWorldAppDelegate.m, HelloWorldViewController.h, and HelloWorldViewController.m. These are the classes that do most of the heavy lifting in our application, in particular managing the view (the UI) that the application’s user sees.

Other Sources

The Other Sources group contains just two files: the prefix header for the project, HelloWorld_Prefix.pch, and main.m. The prefix header file is implicitly included by each of your source files when they’re built; if you need to include a header file in all of the classes in your project, you can add it here. However, it’s unlikely that you’ll need to do this, so you can safely ignore it for the time being. The main.m file contains the main() routine; this is the place where your program begins. In this project, the main.m file handles some memory management duties (discussed in Chapter 4) and then calls the UIApplicationMain function, which is the main controller, responsible for handling the event loop. You’ll almost never have to change anything in the Other Sources group, as the boilerplate code the template generated should serve you fairly well.

Resources

The Resources group contains the .xib files Interface Builder uses to describe your application’s UI.

The HelloWorld-Info.plist (property list) file also plays a role in defining the UI. This property list is an XML file that describes basic information about your application for Xcode and the compiler. You’ll look inside the HelloWorld-Info.plist file later in the chapter when you deploy your application onto your iPhone or iPod touch.

Frameworks

The Frameworks group contains a list of external frameworks that your application links to. These frameworks provide the headers and libraries you need to write software for the iPhone OS.

Products

The Products group contains the application binary that is generated when you compile your application. At first the HelloWorld.app file is shown in red. Xcode knows this file should exist, but since you haven’t yet compiled the application, the file currently doesn’t exist.

Note

If you open the Mac OS X Finder and navigate to where you saved the project, you’ll be able to see how the project files are organized on disk.

Overview of an iPhone application

Figure 3-3 shows a high-level overview of an iPhone application life cycle. This illustrates the main elements of a typical iPhone application. Most iPhone applications make use of the MVC pattern (see Chapter 4 for more details).

A block diagram of a typical iPhone application

Figure 3-3. A block diagram of a typical iPhone application

When the user launches your application by tapping its icon on the home screen, the application’s main() function is called. The main() routine calls the UIApplicationMain function, which is the main application controller responsible for handling the event loop. From this point, the heavy lifting is done by the UIKit framework, which loads the UI and starts the main event loop. During this loop, UIKit dispatches events, such as notification of touches and orientation changes, to your objects and responds to commands issued by your application. When the user performs an action that would cause your application to quit, UIKit notifies your application and begins the termination process.

The application delegate is the core class in your application and receives messages from the main event loop. It is responsible for handling critical system messages. For example, the application delegate handles both the applicationDidFinishLaunching: and theapplicationWillTerminate: messages. Every iPhone application must contain an application delegate object.

The view controller class is responsible for providing views, or a set of views, and presenting them to the user. The class also acts as a delegate and manages your application’s response to some of the standard system behaviors (e.g., a change in device orientation), rearranging and resizing the views it manages in response to these system events.

Declarations, Interfaces, and Implementation

The declaration of a class announces its existence to the compiler, while the implementation of a class consists of the actual code that is the realization of the declaration. Just like the UI the application presents to the world, the class declaration presents an interface to the developer. The declaration declares an interface to your code, and the implementation carries out the task the code has been written to perform.

It’s a common practice to separate the declaration of the class and the implementation into separate header and implementation files. The reason this is done is because header files can be, and usually are, included in multiple source files. Therefore, if we separate the class declaration from its implementation, we make the resultant code more flexible and increase reusability. We can change the underlying implementation of the class without having to recompile the (possibly many) source files that make use of that class.

The application delegate

Let’s begin at the beginning, with the definition of the application delegate class. Click on the HelloWorldAppDelegate.h file, which contains the declaration of the class:

#import <UIKit/UIKit.h>

@class HelloWorldViewController;

@interface HelloWorldAppDelegate : NSObject <UIApplicationDelegate> {

UIWindow *window;

HelloWorldViewController *viewController;

}

@property (nonatomic, retain) IBOutlet UIWindow *window;

@property (nonatomic, retain) IBOutlet

HelloWorldViewController *viewController;

@end

Here we see the app delegate class declaration, beginning with the @interface directive and ending with the @end directive. This is the delegate class that implements the UIApplicationDelegate protocol and receives messages from the UIApplication class. Breaking down this interface directive, we see that our class is called HelloWorldAppDelegate, it’s a subclass of the main object superclass NSObject, and it implements the UIApplicationDelegate protocol.

Let’s look at the corresponding implementation. Click on the HelloWorldAppDelegate.m file to open it in the Xcode editor:

#import "HelloWorldAppDelegate.h"1

#import "HelloWorldViewController.h"

@implementation HelloWorldAppDelegate2

@synthesize window;

@synthesize viewController;

- (void)applicationDidFinishLaunching:(UIApplication *)application {

// Override point for customization after app launch

[window addSubview:viewController.view];3

[window makeKeyAndVisible];4

}

- (void)dealloc {

[viewController release];

[window release];

[super dealloc];

}

@end5

1

The header files are imported with the class declarations for both the HelloWorldAppDelegate and the HelloWorldViewController classes.

2

This is the beginning of the declaration of the Hello World application delegate class.

3

Here, I add the view managed by the viewController object as a subview of the main window.

4

This makes the window visible using the makeKeyAndVisible method.

5

This is the end of the declaration of the Hello World application delegate class.

Quick Access to Class and Method Documentation

In Xcode 3.2 (which comes with Mac OS X 10.6 Snow Leopard), if you Option-double-click on a class or method name, information about that class or method will appear in a small pop-up window. (On most Apple keyboards, the Option key is also labeled as the Alt key, is positioned between the Control and Command keys, and may have the ⌥ symbol on it.) Click the book icon in the top right of the pop up, and you’ll get to see the full documentation. Click on the small .h icon to go to the header file where that class or method is declared. The trick still works in previous versions of Xcode, but instead of a little pop-up window appearing, you’re taken directly to the class documentation.

Option-double-click on the UIApplicationDelegate in the app delegate header file, then click on the book icon to go to the full documentation, and you’ll see the protocol reference. This shows you the methods the app delegate must implement as well as the optional methods (which are marked as such in the protocol documentation). These represent the messages the UIApplication class sends to the application delegate.

In the app delegate declaration file (which is also known as a header file), you’ll see that we declare a UIWindow object as part of the class, and after telling the compiler that HelloWorldViewController is a class using the @class directive, we also declare aHelloWorldViewController object. The UIWindow class defines an object that coordinates the views (the UI) that we see on the iPhone’s screen. Both of these objects are then declared as class properties using the @property name directive.

Properties are a generic way of declaring the data a class provides. In the app delegate implementation, we see that accessor methods for both of our properties are “synthesized” using the @synthesize directive. The synthesis directive tells Objective-C to automatically generate accessor methods for us, and vastly reduces the amount of code we need to write ourselves.

If you return to the declaration (HelloWorldAppDelegate.h) shown earlier, you’ll see that these properties were declared with the symbol IBOutlet. This symbol doesn’t affect how our code is compiled, but it is a place marker to tell Xcode that this object in our code can be connected to a UI component in Interface Builder. This allows the UI constructed in Interface Builder to receive messages from our code. The corresponding IBAction declaration on method declarations, which we’ll meet later, is yet another place marker for Interface Builder, allowing us to connect calling actions in response to events happening in the UI to a method. In many instances, a UI element will also have an associated delegate protocol, and we can declare classes to act as delegates to specific UI elements. Our class will then receive messages when the UI element generates events. For instance, in Chapter 5 you’ll see the UITableView class and associated delegate protocols in action.

Now let’s examine the applicationDidFinishLaunching method. This is where we can insert our own code to customize the application after it launches. See Chapter 5 and the City Guide application for an example of this sort of customization. At the moment, it contains the following:

[window addSubview:viewController.view];

[window makeKeyAndVisible];

You make an object perform an operation by sending a message to the object. Messages are enclosed in square brackets. Inside the brackets, the object receiving the message is on the left side and the message (along with any parameters the message requires) is on the right. The parameters follow the colon (see The Basics of Objective-C Syntax for another example).

The view controller

Next, let’s look inside the HelloWorldViewController class. The interface file for this class is called HelloWorldViewController.h; the implementation file is called HelloWorldViewController.m.

Let’s start with the interface file. Click on the HelloWorldViewController.h file in the Classes group to open the file in the Xcode editor.

Back in HelloWorldAppDelegate.h, the application delegate declared a viewController object of the class HelloWorldViewController, which right now doesn’t contain any methods or properties of its own:

#import <UIKit/UIKit.h>

@interface HelloWorldViewController : UIViewController {

}

@end

However, looking at the header file you’ll see that our HelloWorldViewController class is a subclass of the UIViewController class. This is the class that provides the fundamental view-management model for iPhone applications, and this class is associated in Interface Builder with aNIB file (when you create a view-based project, Xcode automatically creates the associated NIB file). That NIB file contains the UI that will be displayed when we make this view visible.

Note

Although the Interface Builder files end with the .xib extension, Cocoa programmers still refer to them by their old name, NIBs.

Next, click on the HelloWorldViewController.m file in the Classes group and look at the implementation of the class. You’ll see here that the template has provided quite a bit of commented out stub code (code that you need to fill for it to be functional). We’ll return to this stub code later; for now, bear in mind that this subclass relies on its parent class to handle the messages that are left undefined by virtue of being commented out:

#import "HelloWorldViewController.h"

@implementation HelloWorldViewController

/*

// The designated initializer. Override to perform setup that is required

// before the view is loaded.

- (id)initWithNibName:(NSString *)nibNameOrNil

bundle:(NSBundle *)nibBundleOrNil {

if (self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil]) {

// Custom initialization

}

return self;

}

*/

/*

// Implement loadView to create a view hierarchy programmatically,

// without using a nib.

- (void)loadView {

}

*/

/*

// Implement viewDidLoad to do additional setup after loading the view,

// typically from a nib.

- (void)viewDidLoad {

[super viewDidLoad];

}

*/

/*

// Override to allow orientations other than the default portrait orientation.

- (BOOL)shouldAutorotateToInterfaceOrientation:

(UIInterfaceOrientation)interfaceOrientation {

// Return YES for supported orientations

return (interfaceOrientation == UIInterfaceOrientationPortrait);

}

*/

- (void)didReceiveMemoryWarning {

// Releases the view if it doesn't have a superview.

[super didReceiveMemoryWarning];

// Release any cached data, images, etc that aren't in use.

}

- (void)viewDidUnload {

// Release any retained subviews of the main view.

// e.g. self.myOutlet = nil;

}

- (void)dealloc {

[super dealloc];

}

@end

Our Project in Interface Builder

I’ve talked about Interface Builder quite a bit so far, but we haven’t looked at it. Let’s do that now. Interface Builder allows you to create and lay out the UI for your iPhone application visually; it stores your application’s interface in a bundle (an XML file that, for historic reasons, is generally referred to as a NIB file) containing the interface objects and their relationship with your own code. However, unlike almost all other similar design systems that generate code, NIB files are serialized (also known as freeze-dried) objects. In other words, the files contain the read-to-run object instances, rather than code to generate these objects at compile time.

We can use Interface Builder to associate the laid out UI elements with our own code by connecting outlets, actions, and delegates to the UI elements inside the Interface Builder application. However, to do so we must first declare the objects and methods in our code as either an IBOutletor an IBAction where appropriate, and the classes as delegates.

Open the Resources group and double-click on the HelloWorldViewController.xib file. This will open Interface Builder and display the NIB file, as shown in Figure 3-4.

The basic HelloWorldViewController.xib in Interface Builder

Figure 3-4. The basic HelloWorldViewController.xib in Interface Builder

You’ll see four windows: the main Interface Builder window showing the contents of the NIB file; the View window which shows the contents of the NIB’s view; the Library window; and the Attributes window (commonly known as the Inspector window). The Library window contains all the UI elements you can use to build your UI, while the Inspector window allows you to inspect the connections and other properties of a specific UI element.

We’ll discuss the details of what’s going on inside Interface Builder in later chapters; for now, we’re just going to add a button and a label to our view. Then we’ll modify our code so that it knows about those UI elements, and then go back into Interface Builder to connect the UI elements to the objects in our code. At that point, we’ll have a working Hello World application.

Click on the View window and make sure the leftmost tab (the Attributes tab) of the Inspector window is selected. Let’s start by changing the rather dull gray background of the view to white. Click on the Background Color box to bring up the standard Mac OS X color picker. Push the opacity slider to 100% and change the color to something more interesting. In my case, I picked white, which is, I suppose, only marginally more interesting than gray. Close the color picker; the background of your View window should now be a more interesting color.

Now go to the Library and click and drag a label (UILabel) and a round rect button (UIButton) onto your view and drop them in a sensible place. (Make sure Library→Cocoa Touch→Inputs & Values is currently selected in the top pane first.) Delete the placeholder text in the label by double-clicking on the label text to select it and then pressing the Backspace key, and then type some appropriate replacement text for the button—“Push me!” perhaps. Now save your NIB file and return to Xcode; as you can in most Mac applications, you can save your changes by using the keyboard shortcut ⌘-S.

Adding Code

At this point, we need to tell our code about the UI elements we added to our view so that we can return to Interface Builder and make the connections between our new label and button and our code. Open the HelloWorldViewController.h file and add a UILabel and a UIButtondeclaration inside the HelloWorldViewController interface directive:

#import <UIKit/UIKit.h>

@interface HelloWorldViewController : UIViewController {

UILabel *label;

UIButton *button;

}

@property (nonatomic, retain) IBOutlet UILabel *label;

-(IBAction)sayHello:(id) sender;

@end

We also need to declare our UILabel as a property and an IBOutlet. Finally, we need to declare a sayHello method to be called when our button is clicked. We’ll use this to change the text associated with our label and tell the world “Hello!” For now, just duplicate the preceding code; we’ll discuss the layout of Objective-C methods in the next chapter.

Debugging Using NSLog

If you have problems developing this application, or any of the other applications we talk about in the rest of the book, you may want to make use of the NSLog function. You can use this function to print debugging statements to the Console, which you can bring up by clicking on Run→Console in the Xcode menu. Here’s how an NSLog is used in your code:

NSLog( @"Prints this string to the console." );

The NSLog function understands the conventions used by the standard C library printf function, including %f for floats and %d for integers, but in addition uses %@ for objects:

NSLog( @"Prints the UILabel object %@ to the console.", label);

This works by asking the object to describe itself and produces sensible output for many standard objects. This is done by calling the description: method in the object, which returns a string describing the receiving class. The default implementation gives the name of the class, although many objects override this implementation. For example, with the NSArray object, it prints out a list of values.

Next, we need to open the HelloWorldViewController.m file. We need to synthesize our label accessors, which will automatically generate accessor methods for us, and write the implementation of the sayHello method. If you look at the documentation for the UILabel class, you’ll see that all you need to do is to set the text property to change the text displayed by the label:

#import "HelloWorldViewController.h"

@implementation HelloWorldViewController

@synthesize label;

-(IBAction) sayHello:(id) sender {

label.text = @"Hello World";

}

- (void)didReceiveMemoryWarning {

[super didReceiveMemoryWarning];

}

- (void)viewDidUnload {

}

- (void)dealloc {

[label release];

[button release];

[super dealloc];

}

@end

Here @"Hello World" is a constant NSString object.

Connecting the Outlets in Interface Builder

Save both the header and implementation files and return to the HelloWorldViewController.xib file in Interface Builder. We’ve made all the code changes we need to make inside Xcode. In Interface Builder, click on File’s Owner and select the Connections tab (the second from the left, or press ⌘-2) in the Inspector window.

You’ll see that a label outlet and a sayHello: received action are listed. If you briefly visit the Identity tab (the one farthest to the right), you’ll see that the Class Identity of this NIB file is that of a HelloWorldViewController; this class owns the NIB.

By adding code to the HelloWorldViewController class and marking the label object as an IBOutlet and our method as an IBAction, we’ve made these available inside Interface Builder.

Return to the Connections Inspector (⌘-2) and click and drag from the small circle next to your label outlet to the label in the View window. See Figure 3-5 for what this should look like when you do that. Release the mouse button and you should see a new outlet forming in the Connection window. The label outlet is now linked to the Label (label) UI element.

Linking the Label outlet to the label UI element

Figure 3-5. Linking the Label outlet to the label UI element

Now click and drag from the sayHello: received action to your button, as shown in Figure 3-6. When you release the mouse button you’ll be presented with a pop-up menu showing you all of the different types of events that a UIButton can generate. For now, we’re just interested in a simple button push, so select the Touch Up Inside event from the pop-up menu. You should now see a connection formed between the sayHello: received action and the Round Rect Button (Push me!) Touch down event. Whenever this event occurs, our sayHello: method will be called.

Connecting the sayHello action to the button

Figure 3-6. Connecting the sayHello action to the button

We’re done, so save the NIB file and return to Xcode. Make sure Simulator – 3.0 | Debug is selected in the Overview drop down, and click on the Build and Run button in the menu bar. This will start iPhone Simulator and run our code. Click on the “Push me!” button and our initially blank label should now read “Hello World” (see Figure 3-7).

Congratulations, you’ve written your first iPhone application. Now let’s get it to work on your iPhone and iPod touch.

Putting the Application on Your iPhone

Open the HelloWorld-Info.plist file, as shown in Figure 3-8, and edit the “Bundle identifier” line to be the same as the wildcard Bundle Identifier you supplied to Apple in Chapter 2. For instance, I entered uk.co.babilim as my Bundle Identifier, so I would replace the stringcom.yourcompany with uk.co.babilim in the property list file.

iPhone Simulator running our Hello World application

Figure 3-7. iPhone Simulator running our Hello World application

The HelloWorld-Info.plist file; replace com.yourcompany with the Bundle Identifier you gave to Apple in

Figure 3-8. The HelloWorld-Info.plist file; replace com.yourcompany with the Bundle Identifier you gave to Apple in Chapter 2

Note

Remember the following for future reference as you try to run the examples in this book on your device:

If you ever see the error “Code Sign error: a valid provisioning profile matching the application’s Identifier ‘com.yourcompany.ApplicationName’ could not be found,” return to this section and follow these instructions to put your Bundle Identifier in the app’s Info.plistfile.

Now double-click on the HelloWorld project icon at the top of the Groups & Files pane of the Xcode interface; this will open the Project Info window. Click on the Build tab and use the search box, or just scroll down the list of project properties and find the Code Signing Identity associated with this project. Click on the drop-down menu next to the “Any iPhone OS Device” entry and select iPhone Developer, as shown in Figure 3-9.

Selecting the iPhone Developer identity in the Project Info window

Figure 3-9. Selecting the iPhone Developer identity in the Project Info window

Make sure you have completed all the steps needed to use your iPhone or iPod touch for development that we talked about in the preceding chapter, and make sure your device is plugged in and Xcode is aware of it by opening the Organizer window. You should see a green light next to the name of your device in the lefthand pane.

Now change the Active SDK in the Overview drop down in Xcode’s toolbar from “iPhone Simulator 3.0” to “iPhone Device X.Y (Base SDK)”, where X.Y is the version of the most recent iPhone SDK you’ve installed (unless you have some need to compile for an older SDK, you should always use the most recently supported SDK from Apple). If everything seems OK at this point, click the Build and Run button on the toolbar. Xcode should compile the application and transfer it onto your device. You can monitor this process using the Organizer window.

Congratulations, you’ve written and deployed your first iPhone application.

Note

When you become more experienced at developing iPhone applications, and your applications become more complex, you might want to think about using a wireframing application such as Briefs. This allows you to experience how your concept feels without investing the expense and time needed to fully develop the concept into a working application. Since Briefs is image-based, it allows you to mock up your application using anything from scanned paper sketches to full-blown image mockups created by your graphic design team.