Professional Documents
Culture Documents
General
2011-03-08
Apple Inc. 2011 Apple Inc. All rights reserved. No part of this publication may be reproduced, stored in a retrieval system, or transmitted, in any form or by any means, mechanical, electronic, photocopying, recording, or otherwise, without prior written permission of Apple Inc., with the following exceptions: Any person is hereby authorized to store documentation on a single computer for personal use only and to print copies of documentation for personal use provided that the documentation contains Apples copyright notice. The Apple logo is a trademark of Apple Inc. No licenses, express or implied, are granted with respect to any of the technology described in this document. Apple retains all intellectual property rights associated with the technology described in this document. This document is intended to assist application developers to develop applications only for Apple-labeled computers. Apple Inc. 1 Infinite Loop Cupertino, CA 95014 408-996-1010 App Store is a service mark of Apple Inc. Apple, the Apple logo, Cocoa, Cocoa Touch, Instruments, iPhone, Mac, Objective-C, and Xcode are trademarks of Apple Inc., registered in the United States and other countries. iPad is a trademark of Apple Inc. IOS is a trademark or registered trademark of Cisco in the U.S. and other countries and is used under license.
Even though Apple has reviewed this document, APPLE MAKES NO WARRANTY OR REPRESENTATION, EITHER EXPRESS OR IMPLIED, WITH RESPECT TO THIS DOCUMENT, ITS QUALITY, ACCURACY, MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE. AS A RESULT, THIS DOCUMENT IS PROVIDED AS IS, AND YOU, THE READER, ARE ASSUMING THE ENTIRE RISK AS TO ITS QUALITY AND ACCURACY. IN NO EVENT WILL APPLE BE LIABLE FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES RESULTING FROM ANY DEFECT OR INACCURACY IN THIS DOCUMENT, even if advised of the possibility of such damages. THE WARRANTY AND REMEDIES SET FORTH ABOVE ARE EXCLUSIVE AND IN LIEU OF ALL OTHERS, ORAL OR WRITTEN, EXPRESS OR IMPLIED. No Apple dealer, agent, or employee is authorized to make any modification, extension, or addition to this warranty.
Some states do not allow the exclusion or limitation of implied warranties or liability for incidental or consequential damages, so the above limitation or exclusion may not apply to you. This warranty gives you specific legal rights, and you may also have other rights which vary from state to state.
Contents
Introduction
Introduction 7
Organization of This Document 8
Chapter 1
Chapter 2
Chapter 3
Chapter 4
Chapter 5
3
2011-03-08 | 2011 Apple Inc. All Rights Reserved.
CONTENTS
Recap 45 Chapter 6
Chapter 7
Troubleshooting 53
Code and Compiler Warnings 53 Check the Nib Files 53 Delegate Method Names 53
Chapter 8
Next Steps 55
Improve the User Interface 55 Create User Interface Elements Programmatically 55 Install the Application on a Device 56 Add More Functionality 56 Add Unit Tests 57
Appendix A
Code Listings 59
HelloWorldAppDelegate 59 The header file: HelloWorldAppDelegate.h 59 The implementation file: HelloWorldAppDelegate.m 59 MyViewController 60 The header file: MyViewController.h 60 The implementation file: MyViewController.m 60
4
2011-03-08 | 2011 Apple Inc. All Rights Reserved.
Figures
Chapter 3
5
2011-03-08 | 2011 Apple Inc. All Rights Reserved.
FIGURES
6
2011-03-08 | 2011 Apple Inc. All Rights Reserved.
INTRODUCTION
Introduction
This tutorial shows how to create a simple iOS application. It has a text field, a label, and a button. You can type your name into the text field and tap the button to say hello. The application updates the labels text to say Hello, <Name>!:
The goal is not to create a finely polished application, or on the other hand to get an application on screen as quickly as possible, but to illustrate the Three Ts:
Tools: How you create and manage a project using Xcode Technologies: How to make your application respond to user input using standard user interface controls Techniques: The fundamental design patterns and techniques that underlie all Mac OS X development
7
2011-03-08 | 2011 Apple Inc. All Rights Reserved.
INTRODUCTION
Introduction
A secondary goal is to point out other documents that you must also read to fully understand the iOS development tools and techniques. You should read this document if you are just starting development for iOS. You should use this tutorial to get started even if you intend to develop solely for the iPad. Although the tutorial shows the iPhone user interface, the tools and techniques you use are exactly the same as those you use to develop iPad applications. You must, though, already have some familiarity with the basics of computer programming in general and the Objective-C language in particular. If you havent used Objective-C before, read through at least Learning Objective-C: A Primer. Important: To follow this tutorial, you must have installed the iPhone SDK and developer tools available from the iOS Dev Center. This document describes the tools that are available for iPhone SDK v4.3 and latercheck that your version of Xcode is at least 4.0. To learn more about the technologies in Cocoa Touch, read iOS Technology Overview. In this tutorial, little regard is given to the user interface. Presentation is, however, a critical component of a successful iOS application. You should read the iOS Human Interface Guidelines to understand how the user interface might be improved for a full-fledged application. This tutorial does not discuss issues beyond basic application development; in particular, it does not describe how to submit applications to the App Store.
Understanding Fundamental Design Patterns (page 17) provides an overview of the design patterns youll use. Adding a View Controller (page 19) shows you how to customize a view controller class and create an instance of it.
You design the user interface graphically, using Xcode, rather than by writing code. The interface objects are stored in an archive called a nib file.
INTRODUCTION
Introduction
Terminology: Although an interface document may have a .xib extension, historically the extension was .nib (an acronym for NextStep Interface Builder) so they are referred to colloquially as Nib files. The nib file doesnt just describe the layout of user interface elements, it also defines non-user interface elements and connections between elements. The controller object is represented in the nib file. At runtime, when a nib file is loaded the objects are unarchived and restored to the state they were in when you saved the fileincluding all the connections between them.
Inspecting the Nib File (page 29) introduces you to two important concepts: outlets, and the Files Owner proxy object Configuring the View (page 35) shows you how to add and configure the button and text fields. Implementing the View Controller (page 47) walks you through implementing the view controller, including memory management, the changeGreeting: method, and ensuring that the keyboard is dismissed when the user taps Done Troubleshooting (page 53) describes some approaches to solving common problems that you may encounter. Next Steps (page 55) offers suggestions as to what directions you should take next in learning about iOS development.
INTRODUCTION
Introduction
10
CHAPTER 1
In this chapter, you create the project using Xcode and find out how an application launches.
Xcode
The main tool you use to create applications for iOS is XcodeApples IDE (integrated development environment). You can also use it to create a variety of other project types, including Cocoa and command-line utilities.
Xcode
2011-03-08 | 2011 Apple Inc. All Rights Reserved.
11
CHAPTER 1
3. 4. 5.
In the left pane, choose iOS application. Select Window-based Application then click Next. In the Device popup menu, make sure iPhone is selected. Do not select the option to use Core Data. The tutorial does not use Core Data. Do not select the option to use unit tests. The tutorial doesnt discuss how to set up unit tests; however, you should consider using unit tests a best practice for Cocoa development.
6.
Enter HelloWorld as the product name, and a suitable company identifier (if you dont have one, use edu.self). Note: The remainder of the tutorial assumes that you named the project HelloWorld, so the application delegate class is called HelloWorldAppDelegate. If you name your project something else, then the application delegate class will be called YourProjectNameAppDelegate.
7.
Click Next. A sheet appears to allow you to select where your project will be saved.
8.
Select a suitable location for your project (such as the Desktop or a custom Projects directory), then click Save. You do not need to create a version control repository for this project, although in general you are encouraged to do so.
12
Xcode
2011-03-08 | 2011 Apple Inc. All Rights Reserved.
CHAPTER 1
If you havent used Xcode before, take a moment to explore the application. You should read Xcode Workspace Guide to understand the organization of the project window and how to perform basic tasks like editing and saving files. You can now build and run the application to see what Simulator looks like.
Choose Product > Run (or click the Run button in the toolbar).
The iOS Simulator application should launch automatically, and when your application starts up you should simply see a white screen:
Xcode
2011-03-08 | 2011 Apple Inc. All Rights Reserved.
13
CHAPTER 1
To understand where the white screen came from, you need to understand how the application starts up. For now, quit Simulator.
To quit Simulator . . .
Application Bootstrapping
The template project you created already sets up the basic application environment. It creates an application object, connects to the window server, establishes the run loop, and so on. Most of the work is done by the UIApplicationMain function. The main function in main.m calls the UIApplicationMain function:
14
Application Bootstrapping
2011-03-08 | 2011 Apple Inc. All Rights Reserved.
CHAPTER 1
This creates an instance of UIApplication. It also scans the applications Info.plist property list file. The Info.plist file is a dictionary that contains information about the application such as its name and icon. It may contain the name of the nib file the application object should load, specified by the NSMainNibFile key. Nib files contain an archive of user interface elements and other objectsyoull learn more about them later in the tutorial. In your projects Info.plist file you should see: Key Value
NSMainNibFile MainWindow
This means that when the application launches, the MainWindow nib file is loaded.
Click MainWindow.xib in the Resources group in the project window The file has the extension xib but by convention it is referred to as a nib file Xcode displays the file . in the editor area.
The nib file contains several items split into two groups by a dividing line. Above the line are placeholders:
Application Bootstrapping
2011-03-08 | 2011 Apple Inc. All Rights Reserved.
15
CHAPTER 1
The Files Owner proxy object (the pale yellow cube). The Files Owner object is actually the UIApplication instanceFiles Owner is discussed later, in Files Owner (page 30).
A First Responder proxy object. The First Responder is not used in this tutorial but you can learn more about it by reading The Event-Handling System in iOS Application Programming Guide.
An instance of HelloWorldAppDelegate set to be the applications delegate. Delegation is explained in more detail in Understanding Fundamental Design Patterns (page 17).
A window. The window has its background set to white and is set to be visible at launch. Its this window that you see when the application launches.
You use the application delegate to perform custom configuration for the application as a whole, including displaying the window. It shouldnt, though, manage any of the content on the screen beyond the window itselfthats the job of view controllers. A view controller is a special controller responsible for managing a viewthis adheres to the model-view-controller design pattern (explained in more detail in Understanding Fundamental Design Patterns (page 17)). When the application object has completed its setup, it sends its delegate an application:didFinishLaunchingWithOptions: message. This gives the delegate an opportunity to configure the user interface and perform other tasks before the application is displayed.
Recap
In this chapter you created a new project using Xcode and built and ran the default application. You also looked at some of the basic pieces of a project and a nib file, and learned how the application starts up. In the next chapter, youll learn about the design patterns you use when developing a Cocoa application.
16
Recap
2011-03-08 | 2011 Apple Inc. All Rights Reserved.
CHAPTER 2
In this chapter, you learn about the main design patterns youll use in Cocoa applications. Theres not much practical to do in this chapter, but the concepts are fundamental, so allow some time to read and think about it. The main patterns youre going to use in this tutorial are:
Heres a quick summary of these patterns and an indication of where theyll be used in the application.
Delegation
Delegation is a pattern in which one object sends messages to another object specified as its delegate to ask for input or to notify the delegate that an event is occurring. You typically use it as an alternative to class inheritance for extending the functionality of reusable objects. In this application, the application object tells its delegate that the main start-up routines have finished and that the custom configuration can begin. For this application, you want the delegate to create an instance of a controller to set up and manage the view. In addition, the text field will tell its delegate (which in this case will be the same controller) when the user has tapped the Return key. Delegate methods are typically grouped together into a protocol. A protocol is basically just a list of methods. If a class conforms to (or adopts) a protocol, it guarantees that it implements the required methods of a protocol. (Protocols may also include optional methods.) The delegate protocol specifies all the messages an object might send to its delegate. To learn more about protocols and the role they play in Objective-C, see the Protocols chapter in The Objective-C Programming Language.
Model-View-Controller
The Model-View-Controller (or MVC) design pattern sets out three roles for objects in an application. Model objects represent data such as SpaceShips and Weapons in a game, ToDo items and Contacts in a productivity application, or Circles and Squares in a drawing application.
Delegation
2011-03-08 | 2011 Apple Inc. All Rights Reserved.
17
CHAPTER 2
In this application, the model is very simplejust a stringand its not actually used outside of a single method, so from a practical perspective in this application its not even necessary. Its the principle thats important here, though. In other applications the model will be more complicated and accessed from a variety of locations. View objects know how to display data (model objects) and may allow the user to edit the data. In this application, you need a main view to contain several other viewsa text field to capture information from the user, a second text field to display text based on the users input, and a button to let the user tell us that the secondary text should be updated. Controller objects mediate between models and views. In this application, the controller object takes the data from the input text field, stores it in a string, and updates a second text field appropriately. The update is initiated as a result of an action sent by the button.
Target-Action
The target-action mechanism enables a view object that presents a controlthat is, an object such as a button or sliderin response to a user event (such as a click or a tap) to send a message (the action) to another object (the target) that can interpret the message and handle it as an application-specific instruction. In this application, when its tapped, the button tells the controller to update its model and view based on the users input.
18
Target-Action
2011-03-08 | 2011 Apple Inc. All Rights Reserved.
CHAPTER 3
In this application youll need two classes. Xcodes application template provided an application delegate class and an instance is created in the nib file. You need to implement a view controller class and create an instance of it.
19
CHAPTER 3
3. 4.
Select the Cocoa Touch Classes group, then select UIViewController subclass. Click Next. You should see a sheet like this:
Figure 3-1
MyViewController
20
CHAPTER 3
5. 6. 7.
Using the combo box, choose to create a subclass of UIViewController. Using the checkboxes, make sure that Targeted for iPad is not selected, and that With XIB for user interface is selected. Click Next. You should see a sheet like this:
Figure 3-2
MyViewController
Make sure the Add to targets check box is selected. 8. Give the file a new name such as MyViewController. By convention, class names begin with a capital letter. 9. Click Save. Make sure that the files were added to your project.
If you look at the new source files, youll see that stub implementations of various methods are already given to you. These are all you need for the moment; the next task is to create an instance of the class.
21
CHAPTER 3
The property will be an instance of the MyViewController class. The compiler will generate an error, though, if you declare the variable but you dont tell it about the MyViewController class. You could import the header file, but typically in Cocoa you instead provide a forward declarationa promise to the compiler that MyViewController will be defined somewhere else and that it neednt waste time checking for it now. (Doing this also avoids circularities if two classes need to refer to each other and would otherwise include each others header files.) Later, you will import the header file itself in the implementation file. 2. Add a declaration for the view controller property. After the closing brace but before @end, add:
@property (nonatomic, retain) MyViewController *myViewController;
Important: Like C, Objective-C is case-sensitive. MyViewController refers to a class; myViewController is a variable that here contains an instance of MyViewController. A common programming error in Cocoa is to misspell a symbol name, frequently by using a letter of an inappropriate case (for example, tableview instead of tableView). This tutorial deliberately uses MyViewController and myViewController to encourage you to look at the name carefully. When writing code, make sure you use the appropriate symbol. Properties are described in the Declared Properties chapter in The Objective-C Programming Language. Basically, though, this declaration specifies that an instance of HelloWorldAppDelegate has a property that you can access using the getter and setter methods myViewController and setMyViewController: respectively, and that the instance retains the property (retaining is discussed in more detail later). To make sure youre on track, confirm that your HelloWorldAppDelegate class interface file (HelloWorldAppDelegate.h) looks like this (comments are not shown):
#import <UIKit/UIKit.h> @class MyViewController; @interface HelloWorldAppDelegate : NSObject <UIApplicationDelegate> {
22
CHAPTER 3
} @property (nonatomic, retain) IBOutlet UIWindow *window; @property (nonatomic, retain) MyViewController *myViewController; @end
Add the following code as the first statements in the implementation of the application:didFinishLaunchingWithOptions: method:
MyViewController *aViewController = [[MyViewController alloc] initWithNibName:@"MyViewController" bundle:[NSBundle mainBundle]]; [self setMyViewController:aViewController]; [aViewController release];
Theres quite a lot in just these three lines. What they do is:
Create and initialize an instance of the view controller class. Set the new view controller to be the value of the myViewController property using an accessor method. Remember that you didnt separately declare setMyViewController:, it was implied as part of the property declarationsee Adding a View Controller Property (page 22).
23
CHAPTER 3
You create the view controller object using alloc, then initialize it using initWithNibName:bundle:. The init method specifies first the name of the nib file the controller should load and second the bundle in which it should find it. A bundle is an abstraction of a location in the file system that groups code and resources that can be used in an application. The advantages of using bundles over locating resources yourself in the file-system are that: bundles provide a convenient and simple APIthe bundle object can locate a resource just by name; and they take account of localization for you. To learn more about bundles, see Resource Programming Guide. By convention, you own any objects you create using an alloc method (amongst others, see Memory Management Rules). You should also:
Relinquish ownership of any objects you create. Typically use accessor methods to set property values anywhere other than in an initializer method.
The second line in the implementation uses an accessor method to set the property value, and then the third line uses release to relinquish ownership. There are other ways to implement the above. You could, for example, replace the three lines with just two:
MyViewController *aViewController = [[[MyViewController alloc] initWithNibName:@"MyViewController" bundle:[NSBundle mainBundle]] autorelease]; [self setMyViewController:aViewController];
In this version, you use autorelease as a way to relinquish ownership of the new view controller but at some point in the future. To understand this, read Autorelease Pools in the Memory Management Programming Guide. In general, however, you should try to avoid using autorelease wherever possible since it means memory may be reclaimed later than it would be if you used release. You could also replace [self setMyViewController:aViewController]; with:
self.myViewController = aViewController;
The dot notation invokes exactly the same accessor method (setMyViewController:) as in the original implementation. The dot notation simply provides a more compact syntax for accessor methodsespecially when you use nested expressions. Which syntax you choose is largely personal preference, although using the dot syntax does have some additional benefits when used in conjunction with propertiessee Declared Properties in The Objective-C Programming Language. For more about the dot syntax, see Dot Syntax in The Objective-C Programming Language in Objects, Classes, and Messaging in The Objective-C Programming Language.
24
CHAPTER 3
Add the following line of code just before the call to makeKeyAndVisible.
self.window.rootViewController = self.myViewController;
Instead of using the dot syntax, you could also use square brackets:
[[self window] setRootViewController:[self myViewController]];
Both lines of code would compile to the same thing; again you can choose which you feel is more readable. A further important point about this line, though, is that it uses the accessor method to retrieve myViewController. Tip In addition to using accessor methods to set property values (except in the implementation of an init method), you should use accessor methods to get property values, even those of self (except in the implementation of a dealloc method). This helps to preserve encapsulation, and in some cases ensures that a property value is properly initialized before you try to use it. This is discussed in more detail in Housekeeping (page 25).
The final line in the implementation of the application:didFinishLaunchingWithOptions: method from the template:
[window makeKeyAndVisible];
Housekeeping
There are a couple of unfinished tasks to complete: You need to synthesize the accessor methods, andto conform to the rules of memory managementmake sure the view controller is released in the dealloc method. You perform the following tasks in the @implementation block of the class (HelloWorldAppDelegate).
Tell the compiler to synthesize the accessor methods for the view controller, and to use a custom name for the corresponding instance variable.
@synthesize myViewController=_myViewController;
Housekeeping
2011-03-08 | 2011 Apple Inc. All Rights Reserved.
25
CHAPTER 3
Create accessor methods for the myViewController property. Strictly speaking, it means create accessor methods, according to the property declaration, for which the developer hasnt provided an implementation. Since you havent created custom implementations, the compiler will generate a get and set accessor. (If the property were declared as readonly, the compiler would only generate a get accessor.)
Use _myViewController as the name of the instance variable for the myViewController property. Because you didnt declare a _myViewController instance variable, it also tells the compiler to add that to the class as well.
You use the _ prefix for the instance variable to serve as a reminder that you shouldnt access an instance variable directly. From an academic perspective, this helps to preserve encapsulation, but there are two important practical benefits in Cocoa:
Some Cocoa technologies (notably key-value coding) depend on use of accessor methods, and in the appropriate naming of the accessor methods. If you dont use accessor methods, your application may be less able to take advantage of standard Cocoa features. Some property values are created on-demand. If you try to use the instance variable directly, you may get nil or an uninitialized value. (A view controllers view is a good example.)
In the dealloc method, release the view controller as the first statement.
[_myViewController release];
26
CHAPTER 3
{ MyViewController *aViewController = [[MyViewController alloc] initWithNibName:@"MyViewController" bundle:nil]; self.myViewController = aViewController; [aViewController release]; self.window.rootViewController = self.myViewController; [self.window makeKeyAndVisible]; return YES; } /* Other methods omitted from the listing. */ - (void)dealloc { [_myViewController release]; [_window release]; [super dealloc]; } @end
Compile and run the project. Choose Product > Run (or click the Run button in Xcodes toolbar).
Your application should compile without errors and you should again see a white screen in Simulator.
27
CHAPTER 3
Recap
In this section you added a new view controller class and its accompanying nib file. In the application delegate, you declared an instance variable and accessor methods for a view controller instance. You also synthesized the accessor methods and performed a few other housekeeping tasks. Most importantly, though, you created an instance of the view controller and passed its to the window as the root view controller. In the next chapter youll configure the nib file the controller uses to load its view.
28
Recap
2011-03-08 | 2011 Apple Inc. All Rights Reserved.
CHAPTER 4
This chapter introduces two important concepts: outlets and the Files Owner proxy object.
In Xcode, click the view controllers nib file (MyViewController.xib). You should see the file displayed like this:
29
CHAPTER 4
The view is the main view for the view controller. The view controller is represented by the Files Owner proxy. Its important to understand the role of Files Owner, and how to create connections to and from both Files Owner and other objects.
Files Owner
In a nib file, in contrast to the other objects you add to the interface, the Files Owner object is not created when the nib file is loaded. It represents the object set to be the owner in the method that loads the nib filein this case, loadNibNamed:owner:options:. This is discussed in more detail in Resource Programming Guide. In your application, the Files Owner will be the instance of MyViewController. To allow you to make appropriate connections to and from the Files Owner, Xcode has to know what sort of object Files Owner is. You tell Xcode the class of the object using the Identity Inspector. It was actually set when you created the nib file together with the view controller classes, but its useful to look at the inspector now.
30
Files Owner
2011-03-08 | 2011 Apple Inc. All Rights Reserved.
CHAPTER 4
2.
In the Class field of the Custom Class section, you should see MyViewController. Its important to understand that this is just a promise to Interface Builder that the Files Owner will be an instance of MyViewController. Setting the class doesnt ensure that the Files Owner will be an instance of that class. Remember, the Files Owner is simply whatever object is passed as the owner argument to the loadNibNamed:owner:options: method. If its an instance of a different class, the connections you make in the nib file will not be properly established.
31
CHAPTER 4
3.
In the Interface Builder editor window, Control-click Files Owner. This displays a translucent panel showing Files Owners connections.
The utility area and the connections pane both show the same information. You can use whichever is more convenient at any particular time. The only connection at the moment is the view controllers view outlet. An outlet is just a property that happens to connect to an item in a nib file. The outlet connection means that when the nib file is loaded and the UIView instance is unarchived, the view controllers (strictly Files Owners) view property is set to that view.
32
CHAPTER 4
2. 3. 4. 5.
In the utilities area, select the Attributes inspector. In the editor area, select the view. In the Attributes inspector for the view, click the frame of the Background color well to display the Colors panel. In the Colors panel, select a different color.
6. 7.
Save the nib file. Click the Run button in the toolbar to compile and run the project.
Your application should compile without errors and you should again see an appropriately-colored screen in Simulator.
33
CHAPTER 4
Recap
In this section you inspected a nib file, learned about outlets, and set the background color of a view. You also learned more about resource loading and how the view controller loads the nib file. In the next chapter you will add controls to the view.
34
Recap
2011-03-08 | 2011 Apple Inc. All Rights Reserved.
CHAPTER 5
Interface Builder provides a library of objects that you can add to a nib file. Some of these are user interface elements such as buttons and text fields; others are controller objects such as view controllers. Your nib file already contains a viewnow you just need to add the button and text fields.
To add objects to the nib file and lay them out appropriately . . .
1. 2. 3. In Xcode, select the view controllers nib file. In the utilities area, display the object library. Add a button (UIButton), a text field (UITextField), and a label (UILabel) to the view. You can drag view items from the library and drop them onto the view just as you might in a drawing application.
35
CHAPTER 5
4.
Lay out the elements appropriately. You can then resize the items using resize handles where appropriate, and reposition them by dragging. As you move items within the view, alignment guides are displayed as dashed blue lines.
36
CHAPTER 5
5.
Add a placeholder string Your Name to the text field by entering it in the Text Field Attributes inspector. Resize the label so that it extends for the width of the view. Delete the text (Label) from the label either using the Label Attributes inspector or by selecting the text in the label itself (double-click to make a selection) and press Delete. Add a title to the button by double-clicking inside the button and typing Hello. Use the inspector to set the text alignment for the text field and label to centered.
37
CHAPTER 5
6.
In the view section of the labels Label Attributes inspector, select Clear Context Before Drawing. This ensures that when you update the greeting the previous string is removed before the new one is drawn. If you dont do this, the strings are drawn on top of each other.
There are several other changes to make to the text fieldit might be fairly obvious that the first change applies to the text field, but the others are less obvious. First, you might want to ensure that names are automatically capitalized. Second, you might want to make sure that the keyboard associated with the text field is configured for entering names, and that the keyboard displays a Done button. The guiding principle here is this: You know when youre putting it on screen what a text field will contain. You therefore design the text field to make sure that at runtime the keyboard can configure itself to best suit the users task. You make all of these settings using text input traits.
38
CHAPTER 5
In the Keyboard Type pop-up menu, select Default. In the Keyboard Return Key pop-up menu, select Done.
4.
If you build and run your application in Xcode, when it launches you should see the user interface elements as you positioned them. If you press the button, it should highlight, and if you tap inside the text field, the keyboard should appear. At the moment, though, after the keyboard appears, theres no way to dismiss it. To remedy this, and add other functionality, you need to make appropriate connections to and from the view controller. These are described in the next section.
Make Connections
You can create and connect outlets and actions in Xcode by dragging from a nib file to the appropriate source file. Whereas this makes it easy to add code to support outlets and actions, it adds a conceptual level of indirection. Although youre dragging to the source file, the actual connections are made in the nib file itself, to the object for which the header file is the declarationin this case, the view controller represented by Files Owner. You want to add an action method to the view controller; when the button is activated it should send a changeGreeting: message to the view controller. For the button, you want to create an action called changeGreeting::
Make Connections
2011-03-08 | 2011 Apple Inc. All Rights Reserved.
39
CHAPTER 5
5.
Set the connection type to Action. Set the name to changeGreeting:. Set the type to id. It doesnt matter what sort of object sends the message.
Set the event to touch up inside. The message should be sent if the user lifts their finger inside the buttonthis corresponds to UIControlEventTouchUpInside.
6.
Click Connect.
You accomplished two things by adding an action for a button: 1. Added appropriate code to the view controller class. You added the action method declaration to the header file:
- (IBAction)changeGreeting:(id)sender;
40
Make Connections
2011-03-08 | 2011 Apple Inc. All Rights Reserved.
CHAPTER 5
IBAction is a special keyword that is used only to tell Interface Builder to treat a method as an action for target/action connections. Its defined to void.
2.
Established a connection from the button to the view controller, as represented by the Files Owner. Establishing the connection is the equivalent of invoking addTarget:action:forControlEvents: on the button, with the target being Fies Owner, the action being the changeGreeting: selector, and the control events containing just UIControlEventTouchUpInside.
You follow similar operations to add outlets for the text field and label.
Make Connections
2011-03-08 | 2011 Apple Inc. All Rights Reserved.
41
CHAPTER 5
5.
Configure the text fields connection as an outlet. Add an outlet from the view controller connected to the text field.
Set the connection type to Outlet. Set the name to textField. You can call the outlet whatever you want, but it makes your code more understandable if the name bears some relationship with the thing it represents.
Set the type to UITextField. You want to make sure the outlet can only connect to a text field.
6.
Click Connect.
You accomplished two things by adding an outlet for the text field: 1. You added appropriate code to the view controller class. The property declaration to the header file:
@property (nonatomic, retain) IBOutlet UITextField *textField;
to the viewDidUnload method. Property declarations and the synthesize keyword are explained in more detail in The Users Name Property (page 47).
IBOutlet is a special keyword that is used only to tell Interface Builder to treat a property as an outlet.
Its actually defined as nothing so it has no effect at compile time. 2. You established a connection from the the view controller (as represented by the Files Owner) to the text field. Establishing a connection from the the view controller does the equivalent of invoking setTextField: on the view controller, passing the text field as the argument. Now configure the label. Follow the same steps as for the text field, but with appropriate changes to the configuration.
42
Make Connections
2011-03-08 | 2011 Apple Inc. All Rights Reserved.
CHAPTER 5
Follow the same steps as for the text field. In the connection configuration dialog:
Set the connection type to Outlet. Set the name to label. Set the type to UILabel.
43
CHAPTER 5
Testing
You can now test the application.
Click Run. Make sure that all the files are saved.
You should find that the button works (it highlights when you tap it). You should also find that if you touch in the text field, the keyboard appears and you enter text. There is, however, no way to dismiss the keyboard. To do that, you have to implement the relevant delegate method. Youll do that in the next chapter.
44
Testing
2011-03-08 | 2011 Apple Inc. All Rights Reserved.
CHAPTER 5
Recap
You configured the nib file with appropriate connections; in doing so, you also updated the header and implementation files to support the outlets and action. Theres no need to use the Xcode feature to add the source code at the same time as establishing a connection; you can add the property and method declarations to the header file yourself, and then make the connections like you did with the text fields delegate. Typically, though, you make fewer mistakes (and have less typing to do) if you let the tools do as much of the work as they can.
Recap
2011-03-08 | 2011 Apple Inc. All Rights Reserved.
45
CHAPTER 5
46
Recap
2011-03-08 | 2011 Apple Inc. All Rights Reserved.
CHAPTER 6
There are several parts to implementing the view controller. You need to add a property for the users name including memory management, implement the changeGreeting: method, and ensure that the keyboard is dismissed when the user taps Done.
Add a @property statement for a string called userName. The property declaration looks like this.
@property (nonatomic, copy) NSString *userName;
To complete the implementation, you also need to tell the compiler to synthesize the accessor methods, and update the dealloc method. You add the implementation parts to the view controllers implementation file (MyViewController.m).
47
CHAPTER 6
Synthesize the userName property by adding the following after the @implementation MyViewController line:
@synthesize userName;
This tells the compiler to synthesize accessor methods for these property according to the specification you gave in the interface file. The declaration of the userName property is @property (nonatomic, copy) NSString *userName;), so the compiler generates two accessor methods: - (NSString *)userName and - (void)setUserName:(NSString *)newUserName. In the setUserName: method a copy is made of the string thats passed in. This is useful to ensure encapsulation (the passed-in string might be mutableyou want to make sure that the controller maintains its own copy). For more about encapsulation, see Mechanisms Of Abstraction in Object-Oriented Programming with Objective-C. You must relinquish ownership in the dealloc method because the property declaration specifies that the view controller owns the instance variables (retain and copy imply ownership; see Memory Management Rules in Memory Management Programming Guide).
To correctly handle memory management for the user name property in dealloc . . .
In the dealloc method, release userName by adding the following before the invocation of super:
[userName release];
48
CHAPTER 6
self.userName = textField.text; retrieves the text from the text field and sets the controllers userName property to the result.
In this case, you dont actually use the user name anywhere else, but its important to understand its role. Its the very simple model object that the view controller is managing. In general, the controller should maintain information about application data in its own model objectsapplication data shouldnt be stored in user interface elements.
The initWithFormat: method creates a new string that follows the format specified by the format string, like the printf function.
%@ indicates that a string object should be substituted. To learn more about strings, see String Programming
Guide.
49
CHAPTER 6
In an iOS application, the keyboard is shown automatically when an element that allows text entry becomes the first responder; it is dismissed automatically when the element loses first responder status. (You can learn more about first responder by reading The Event-Handling System in iOS Application Programming Guide.) Theres no way to directly message the keyboard; you can, however, make it appear or disappear as a side-effect of toggling the first responder status of a text-entry element. The UITextFieldDelegate protocol includes a method, textFieldShouldReturn:, that the text field calls whenever the user taps the Return button (whatever text the button shows). Because you set the view controller as the text fields delegate, you can implement this method to force the text field to lose first responder status by sending it the resignFirstResponder messagewhich has the side-effect of dismissing the keyboard. The view controller must adopt the UITextFieldDelegateprotocol. To specify that a class adopts a protocol, in the interface add the name of the protocol in angle brackets (<>) after the name of the class from which your class inherits.
This declaration specifies that the view controller class adopts the UITextFieldDelegate protocol. 2. In the view controllers implementation file (MyViewController.m), implement the textFieldShouldReturn: method. The method should tell the text field to resign first responder status. The implementation might look like this:
- (BOOL)textFieldShouldReturn:(UITextField *)theTextField { if (theTextField == textField) { [textField resignFirstResponder]; } return YES; }
In this application, its not really necessary to include the theTextField == textField test since theres only one text field. Its worth pointing out the pattern, though, since there may be occasions when your object is the delegate of more than one object of the same type and you may need to differentiate between them.
50
CHAPTER 6
If the application doesnt behave as you expect, you need to troubleshoot (see Troubleshooting (page 53)).
Recap
You finished the implementation of the view controller and so completed your first iOS application. Congratulations. Take a moment to think about how the view controller fits into the overall application architecture. You will use view controllers in all iOS applications you write. Then take a break, and start to think about what you should do next.
Recap
2011-03-08 | 2011 Apple Inc. All Rights Reserved.
51
CHAPTER 6
52
Recap
2011-03-08 | 2011 Apple Inc. All Rights Reserved.
CHAPTER 7
Troubleshooting
This section describes some approaches to solving common problems that you may encounter.
If your user interface doesnt reflect changes you made to the nib file, make sure you saved the nib file before you built the project. If the text doesnt update when you tap the button, it might be that you didnt connect the buttons action to the view controller, or connect the view controllers outlets to the text field or label. If the keyboard does not disappear when you tap Done, you may not have connected the text fields delegate or connected the view controllers textField outlet to the text field (see Make the Text Fields Delegate Connection (page 43)). If you have connected the delegate, there may be a more subtle problem (see Delegate Method Names (page 53)).
53
CHAPTER 7
Troubleshooting
54
CHAPTER 8
Next Steps
This chapter suggests directions you might take next in learning about iOS development.
55
CHAPTER 8
Next Steps
Notice that theres quite a lot of code compared with how easy it was to create and configure the text field in Xcode. In the application delegate, create the view controller instance using alloc and init instead of alloc and
initWithNibName:bundle:
Build and run the application. Make sure it behaves as it did before.
Write a custom view. Rather than using a view as a canvas on which to drop prebuilt user interface controls, you might try writing a custom view that draws its own content or responds to touch events. For inspiration, look at examples such as MoveMe and Metronome. Use a table view. Although you used Xcode to layout the user interface for this application, many applications actually use table views to lay out the interface. This makes it easy to create an interface that extends beyond the bounds of the screenallowing the user to easily scroll to reveal additional elements. You should first investigate how to create a simple list using a table view. There are several sample code projects that you can look atincluding TableViewSuitethen you can create your own. Use a navigation controller. Navigation controllers and tab bar controllers provide an architecture that allow you to create drill-down style interfaces and let the user select different views in your application. Navigation controllers often work in conjunction with table views, but both navigation controllers and tab bar controllers work together with view controllers. Have a look at some of the sample applicationssuch as SimpleDrillDownthat use navigation controllers and expand on them to create your own applications. Localize your app. You can often increase the size of your potential marketplace by localizing your application. Internationalization is the process of making your application localizable. To learn more about internationalization, read Internationalization Programming Topics. Optimize your code. Performance is critical to good user experience on iOS. You should learn to use the various performance tools provided with Mac OS Xin particular Instrumentsto tune your application so that it minimizes its resource requirements.
56
CHAPTER 8
Next Steps
The most important thing is to try out new ideas and to experimentthere are many code samples you can look at for inspiration, and the documentation will help you to understand concepts and programming interfaces.
57
CHAPTER 8
Next Steps
58
APPENDIX A
Code Listings
This appendix provides listings for the two classes you define. The listings dont show comments and other method implementations from the file templates.
HelloWorldAppDelegate
The header file: HelloWorldAppDelegate.h
#import <UIKit/UIKit.h> @class MyViewController; @interface HelloWorldAppDelegate : NSObject <UIApplicationDelegate> { } @property (nonatomic, retain) IBOutlet UIWindow *window; @property (nonatomic, retain) MyViewController *myViewController; @end
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { MyViewController *aViewController = [[MyViewController alloc] initWithNibName:@"MyViewController" bundle:[NSBundle mainBundle]]; [self setMyViewController:aViewController]; [aViewController release]; self.window.rootViewController = self.myViewController; [self.window makeKeyAndVisible]; return YES; }
HelloWorldAppDelegate
2011-03-08 | 2011 Apple Inc. All Rights Reserved.
59
APPENDIX A
Code Listings
// Other methods from the template omitted - (void)dealloc { [_myViewController release]; [_window release]; [super dealloc]; } @end
MyViewController
The header file: MyViewController.h
#import <UIKit/UIKit.h> @interface MyViewController : UIViewController <UITextFieldDelegate> { UITextField *textField; UILabel *label; NSString *userName; } @property (nonatomic, retain) IBOutlet UITextField *textField; @property (nonatomic, retain) IBOutlet UILabel *label; @property (nonatomic, copy) NSString *userName; - (IBAction)changeGreeting:(id)sender; @end
- (BOOL)textFieldShouldReturn:(UITextField *)theTextField { if (theTextField == textField) { [textField resignFirstResponder]; } return YES; } - (void)dealloc { [textField release]; [label release];
60
MyViewController
2011-03-08 | 2011 Apple Inc. All Rights Reserved.
APPENDIX A
Code Listings
[userName release]; [super dealloc]; } - (IBAction)changeGreeting:(id)sender { self.userName = textField.text; NSString *nameString = self.userName; if ([nameString length] == 0) { nameString = @"World"; } NSString *greeting = [[NSString alloc] initWithFormat:@"Hello, %@!", nameString]; label.text = greeting; [greeting release]; } // Other methods from the template omitted. @end
MyViewController
2011-03-08 | 2011 Apple Inc. All Rights Reserved.
61
APPENDIX A
Code Listings
62
MyViewController
2011-03-08 | 2011 Apple Inc. All Rights Reserved.
REVISION HISTORY
This table describes the changes to Your First iOS Application. Date 2011-03-08 2010-10-12 2010-07-01 2010-03-15 2009-10-08 2009-08-10 Notes Updated for Xcode 4. Corrected a bad link. Updated for iOS 4. Updated for iOS 3.2. Emphasized need to connect text field in Interface Builder. Removed a reference to dot syntax for an example that used an accessor method directly. Updated for iOS 3.0. Corrected typographical errors. Clarified description of the target-action design pattern. Minor corrections and clarifications. New document that introduces application development for iPhone.
63
2011-03-08 | 2011 Apple Inc. All Rights Reserved.
REVISION HISTORY
64
2011-03-08 | 2011 Apple Inc. All Rights Reserved.