Chapter 1. getting started: Going mobile

I just don't see what all this iPhone fuss is about. My phone works just fine...

The iPhone changed everything. It's a gaming platform, a personal organizer, a full web-browser, oh yeah, and a phone. The iPhone is one of the most exciting devices to come out in some time, and with the opening of the App Store, it's an opportunity for independent developers to compete worldwide with big-name software companies. All you need to release your own app are a couple of software tools, some knowledge, and enthusiasm. Apple provides the software, and we'll help you with the knowledge; we're sure you've got the enthusiasm covered.

There's a lot of buzz and a lot of money tied up in the App Store...

Mobile applications aren't just ported desktop apps

There are about a billion good reasons to get into the App Store, and now it's time for you to jump in. To get there from here, you'll learn about designing and implementing an iPhone app, but it's not the same as developing for the desktop, or writing a web application.

It's important to think an iPhone application through from the beginning. You need to constantly ask yourself "What is it the user is trying to do?" Get rid of everything else, minimize the input they have to provide, and keep it focused.

This is NOT the same as this

iPhone apps are not small desktop apps

There's a lot of talk about how the iPhone is a small computer that people carry with them. That's definitely true, but it doesn't mean iPhone apps are just small desktop apps. Some of the most important issues that you'll encounter designing an app for the iPhone:

  • iPhones have a small screen and are task-focused

    Even with the iPhone's fantastic screen, it's still relatively small (320×480). You need to put real thought into every screen and keep it focused on the specific task the user is doing.

  • iPhones have limited CPU and memory

    On top of that, there's no virtual memory and every bit of CPU oomph you use means more battery drain. iPhone OS monitors the system closely and if you go crazy with memory usage, it'll just kill your app. And no one wants that.

  • Only one application can run at a time

    If it's your application running, why should you care? Because if anything else happens, like the phone rings, a text message comes in, the user clicks on a link, etc., your app gets shut down and the user moves on to another application. You need to be able to gracefully exit at any time and be able to put users back into a reasonable spot when they return.

Anatomy of an iPhone app

Before we dive into creating our first app, let's take a look at what makes up a typical iPhone app.

First we have one or more views...

iPhone apps are made up of one or more views—in a normal app, these views have GUI components on them like text fields, buttons, labels, etc. Games have views too, but typically don't use the normal GUI components. Games generally require their own custom interfaces that are created with things like OpenGL or Quartz.

Views can be built using code, graphically using Interface Builder, or some combination of both. Most apps use a mix.

...then the code that makes the views work...

iPhone apps have a clean separation between the GUI (the view) and the actual code that provides the application logic. In general, each view has a View Controller behind it that reacts to button presses, table row selection, tilting the phone, etc. This code is almost always written in Objective-C using Apple's IDE (integrated development environment), Xcode.

Xcode is the IDE of choice for writing iPhone apps. It includes a number of application templates to get you started.

...and any other resources, all packaged into your application.

If you're new to developing for OS X you might be surprised to find out that applications (iPhone and full desktop apps) are really just directories. Any app directory contains the actual binary executable, some metadata about the application (the author, the icon filename, code signatures, etc.) and any other application resources like images, application data, help files, etc. iPhone applications behave the same way, so when you tell Xcode about other resources your application needs, it will bundle them up for you when you build the application.

Every iPhone app has some resources associated with it. At a minimum, your application will have an icon file, an Info.plist that has information about the application itself, and the actual binary. Other common resources are interface files, called nibs.

Pictures

Date

Now let's get started on your first iPhone App...

Mike can't make a decision

Mike's a great guy, but he never knows what he wants to do. Help him save time waffling about what to do, and give him a straightforward answer.

The way I see it is I already made the decision to buy an iPhone... I shouldn't have to think again!

We'll write Mike an app.

Mike has an iPhone, so let's write him an app that requires a simple button push to tell him what to do when he needs to make a decision.

Mike

Make a good first impression

When users start up your application, the first thing they see is your view. It needs to be usable and focused on what your application is supposed to do. Throughout this book, whenever we start a new application, we're going to take a little time to sketch up what we want it to look like.

Our first application is pretty straightforward: it is going to be a single view with a button that Mike can press to get a decision. To keep things simple, we'll change the label of the button to show what he should do after he pushes it.

This is the status bar – your app can choose to hide it, but unless you're writing a game, you should probably leave it.

Press the button and the label text will change to tell Mike what he should do.

This is the iPhone simulator – this lets you run and test your application without using a real phone. We'll talk more about it later.

The iPhone screen is 320 × 480 pixels.

We'll sketch up our GUIs for each application before we build them. Pen & paper are some of the best mockup tools you could use.

Let's call it iDecide.

iDecide

This is a button

What should I do?

Now that we know what to build, let's get into the tools.

It all starts with the iPhone SDK

It's time to go get some tools. Head over to http://developer.apple.com/iphone. You can download the SDK (and other useful Apple development resources) for free with the basic registration, but to distribute a completed app on the App Store or install your app on the iPhone for testing you need to become a paid Standard or Enterprise Developer. The SDK comes with a simulator for testing directly on your Mac, so free registration is all you'll need for now.

The SDK comes with Xcode, Instruments, Interface Builder, and the iPhone Simulator. Code for the iPhone is written in Xcode using Objective-C. Interface Builder is used for graphically editing GUIs, Instruments helps you assess memory usage and performance for your app, and the Simulator is used for testing.

  • Register as a developer at http://developer.apple.com/iphone.

  • Download the latest SDK; this book is based on the 3.1 SDK. Just look for the Download button at the top of the page.

  • Install the SDK. Once the Installation completes, you can find Xcode.app in /Developer/Applications. Just double-click it to start it up.

You will probably want to drag it onto your Dock—we're going to be using it a lot.

there are no: Dumb Questions

Q:

What are the most important things to consider when developing a mobile app?

A:

There are two key things to keep in mind when developing a mobile application. First, the device has limited resources: memory, CPU, storage, Net access speed (if they have access at all), etc. Second, usage patterns are different for mobile applications. Mobile apps are generally convenience applications—users want to fire up your application, quickly accomplish their goal, and go back to what they were doing in the real world.

Q:

I've developed for mobile platforms before, and it was a mess. Nothing worked the same between different devices, you couldn't count on the screen size, they didn't even have the same number of buttons on different devices! Is this any better?

A:

YES! For the most part, developing for iPhone avoids these problems. iPhones all have a 320×480 screen, an accelerometer, a single home key, etc. However...

Q:

There are several different models of the iPhone out there. Are they all the same? What about the iPod Touch?

A:

Not all iPhone and iPod Touch devices are the same. For example, not all devices have a camera or GPS. Net access speeds vary by device as well depending on whether they're connected to EDGE, 3G, or Wifi. To make matters more complicated, the iPhone 3GS has a faster processor and better video card than previous iPhone models. If you take advantage of any features that might not be present on all devices you must make sure your code can handle not having that feature available. Apple will test for this (for example, trying to use the camera on a first generation iPod Touch) and reject your application if it doesn't accomodate a device properly.

Q:

What language does the iPhone use?

A:

iPhone apps are generally written in Objective-C, an object-oriented language that is also used for Mac development. However, you can use C and even C++ on the iPhone. Since the GUI and Core Framework libraries for the iPhone are written in Objective-C, most developers use Objective-C for their application; however, it's not uncommon to see support libraries written in C.

Q:

Do I have to use an IDE? I'm really a command-line kinda developer.

A:

Technically speaking, no, you don't have to use the Xcode IDE for straight development. However, the IDE makes iPhone development so much easier that you really should ask yourself if you have a good reason for avoiding it, especially since to deploy onto an actual iPhone or the simulator for testing, it's mandatory. This book uses the Xcode IDE as well as other Apple development tools like Interface Builder, and we encourage you to at least try them out before you abandon them.

Q:

Can I give applications I write out to friends?

A:

Yes and no. First, if you want to put an application on anyone's actual device (including your own) you'll need to become a registered Apple iPhone Developer. Once you've done that, you can register a device and install your application on it. However, that's not really a great way to get your application out there, and Apple limits how many devices you can register this way. It's great for testing your application, but not how you want to go about passing it around.

A better way is to submit your application to the iTunes App Store. You can choose to distribute your application for free or charge for it, but by distributing it through the iTunes App Store, you make your application available to the world (and maybe make some money, too!). We'll talk more about distributing apps later in the book.

Q:

Can I develop an app for the iPhone then rebuild it for other phones like Windows Mobile, Android, or Blackberries?

A:

In a word, no. When you develop for iPhone, you use Apple's iPhone frameworks, like Cocoa Touch, as well as Objective-C. Neither of these are available on other devices.

Now let's get started. Launch Xcode...

Xcode includes app templates to help you get started

When you start Xcode, you'll get a welcome screen where you can select Create a New Project. You'll get this dialog:

This is the very same Xcode that you'd use to develop for the Mac. Since we're working with the iPhone, make sure iPhone OS Application is selected..

These are the basic App templates. Based on your selection, different code and files are populated for you.

If you click on each project type, the description here will help fill you in on some details.

As we go through the book, we'll use different types of projects and discuss why you'd choose one over another for each app. For iDecide, we have one screen (or view) that we're not going to be flipping or anything, so start with the View-based Application and name it iDecide.

The Xcode template includes more than just source code.

Files

Header files describe the interface for the classes in the project you selected.

The .m files contain the basic implementation files for the app type you selected.

Resources

Databases, plists, and other types of data are stored in here for your app.

This is the folder where you'll store the icon for your app and any other images you need.

Frameworks

Frameworks are development libraries – depending on what your application does, you'll need different frameworks. For example, there's a MapKit framework, a Core Data framework, etc.

Xcode will generate at least one view for your template, which is a *.xib file.

Root View

The frameworks that your template type needs are already included.

Xcode is the hub of your iPhone project...

When Xcode opens with your new View-based project, it will be populated with all of the files that you see below. We'll be using some of the other tools that came with the SDK (especially Interface Builder and the Simulator), but they are all working with the files that are included here.

The files and frameworks shown were stubbed out based on our selection of a View-based application. As we go forward, we'll use different types of apps and that will lead to different defaults.

Class files are the Objective C files that your App will use – most code will be written here.

Other sources include your main function and precompiled info.

Resources contains all of your Interface Builder (.xib) files, pictures, data, and other stuff that your app will need to run.

Frameworks shows a list of the libraries you're using.

Folder groupings in Xcode are not file locations.

Here is where you can configure whether to build your app for the simulator or a real device. We'll stick with the simulator throughout the book.

The toolbar includes options for setting breakpoints, building and running your application, and more. We'll mostly use Build and Debug.

The Detail View shows a list of the selected files. Whatever is selected will show here

You don't have to group your files this way, but this is the default from the template. This grouping works well for us, so we'll leave it alone.

The Editor Pane shows your file with the appropriate editor loaded and allows you to work directly with the code, plist, whatever.

...and plays a role in every part of writing your app

Xcode is much more than just a text editor. As you've already seen, Xcode includes the templates to get you started developing an application. Depending on your application, you may use all of a template or just parts of it, but you'll almost always start with one of them. Once you get your basic app template in place, you'll use Xcode for a lot more:

  • Maintaining your project resources

    Xcode will create a new directory for your project and sort the various files into subdirectories. You don't have to stick with the default layout, but if you decide to reorganize, do it from within Xcode. Xcode also has built-in support for version control tools like Subversion and can be used to checkout and commit your project changes.

  • Editing your code and resources

    You'll use Xcode to edit your application code, and it supports a variety of languages beyond just Objective-C. Xcode also has a number of built-in editors for resource files like plists (we'll talk more about them later on). For resources Xcode doesn't handle natively, like UI definition (.xib) files, double-clicking on one of those files in Xcode will launch the appropriate editor, in this case Interface Builder. Some file types Xcode can only view, like pictures, or it will merely list, like sound files.

  • Building and testing your application

    Xcode comes with all of the compilers necessary to build your code and generate a working application. Once your application is compiled, Xcode can install it on the iPhone Simulator or a real device. Xcode includes a top-notch debugger with both graphical and command-line interfaces to let you debug your application. You can launch profiling tools like Instruments to check for memory or performance issues.

  • Prepare your application for sale

    Once you get your application thoroughly tested and you're ready to sell it, Xcode manages your provisioning profiles and code signing certificates that let you put your application on real devices or upload it to the iTunes App Store for sale.

OK, enough talking about Xcode: double-click on iDecideViewController.xib and we'll start with the view.

Build your interface using... Interface Builder

When you open any *.xib file in Interface Builder, it will automatically show the Main window, your view, and a library of UI elements. Interface Builder allows you to drag and drop any of the basic library elements into your view, edit them, and work with the connections between the code and these elements. All of these elements come from the Cocoa Touch framework, a custom UI framework for the iPhone and the iPod Touch.

This is the Main window. It shows the objects and views that are currently created for that particular nib. File's Owner and the First Responder exist for every nib, and the others will vary. We'll talk about both in much greater detail later.

The library shows all of the elements you can choose from to drop into your view. If you scroll around, you'll see there are a lot of options.

Each screen in your application is a view. This shows what your view will look like (minus any data that needs to be loaded) in the app. You can build views using code and/or by dragging and dropping controls using Interface Builder. We'll use Interface Builder for iDecide.

A GUI builder sure sounds easier. I guess it just spits out Objective-C code into my files?

No—Interface Builder creates nibs.

Nibs (which have .xib extensions) are XML documents that are loaded by the framework when the app starts up. We'll talk a lot more about this in the next chapter, but for now it's just important to understand that Interface Builder is not creating Objective-C code. It's creating an XML description of the GUI you're building, and the Cocoa Touch framework uses that to actually create the buttons and whatnot for your application at runtime. Everything we do in Interface Builder could be done in pure Objective-C code, but as you'll see, there are some things that are really just easier to lay out with a GUI builder.

...then the Cocoa Touch framework built into our app uses the description in the .xib file to create the actual Cocoa Touch objects in our view.

iDecideViewController.xib

We create the XML description using Interface Builder...

And that view is what the user sees when they run our app.

What should I do?

Views for iPhone Apps are called nibs, and have an .xib extension.

Add the button to your view

To add elements to the view, all you need to do is drag and drop the elements you want onto your view. For our app, we just need a button with a label on it.

Drag the rectangular button onto the view.

The initial size of the button will be small, so resize it to be a bit bigger. Just grab the corners of the button and pull.

Drag the label onto the button.

Edit the new label on the button to say "What should I do?" by double-clicking on the "label"and type the new text, then move the text around to center it on the button.

The iPhone Simulator lets you test your app on your Mac

The Simulator is a great tool for testing your apps quickly and for free. It doesn't come with all of the applications that a real phone does, but for the most part it behaves the same way. When you first start the simulator you see the Springboard, just like on a real iPhone, with iDecide installed (and a default icon that you can change later). Xcode then opens the app and your code is running.

There are some differences between using the Simulator and your iPhone. For starters, shaking and rotating your Mac won't accomplish anything. To approximate rotation and check landscape and portrait views, there are some commands under the Hardware menu.

there are no: Dumb Questions

Q:

Are there other things that don't work on the Simulator?

A:

The Simulator can only work with some gestures, network accessibility and core location are limited, and it doesn't have an accelerometer or camera. For more information, reference Apple's iPhone OS 3.0 Library documentation, via the Help menu in the Simulator.

The Simulator is great for getting started with your application, but at some point you have to move over to a real device. Also, be aware that the iPod Touch and the iPhone are two different devices with different capabilities. You really should test on both, which means you'll need to join one of the paid programs.

Q:

What's with this whole nibs have a xib extension thing?

A:

That's an odd artifact showing the roots of OS X. Nibs date back to the NeXTStep days, before NeXT was acquired by Apple. In OS X Leopard, Apple released a new format for nib files based on an XML Schema and changed the extension to xib. So, while the format is XML and they have a .xib extension, people still refer to them as nibs. You'll see more NeXTStep heritage in library class names too—almost everything starts with "NS", short for NeXTStep.

Q:

Why didn't anything happen when I clicked on the button in the Simulator?

A:

It's temping to expect that button to just work out of the gate, given how much XCode sets up for you. However, if you think about what we've done, there has been some XML created to load a framework and draw a button, but we didn't tell it to do anything with that button yet...

OK, so Interface Builder created XML, but we still need to write code to implement the button press, right?

UI behavior is implemented in Objective-C.

Interface Builder creates your button, but to make that button actually do something, you'll need to code what it should do.

Controls trigger events in Objective-C when things happen to them, like the button being pressed or text changing in a text field. For events like button presses, Interface Builder has to connect the view controls with code in your controller class for action methods, tagged with IBAction (for Interface Builder Action). We'll talk more about the Objective-C syntax later, but for now, you'll need to declare a method in your header (.h) file and the implementation in the .m.

This line declares a method called buttonPressed that Interface Builder will recognize as a possible callback.

The .xib file describes the button as you configured it in Interface Builder.

.xib

iDecideViewController.xib

Button

-(IBAction)
 buttonPressed:(id)
 sender;

-(IBAction)
 buttonPressed:(id)
 sender
 {

 method that the button
 calls
}

iDecideViewController.h

You provide the method implementation in the .m file. Here's where you code up what should actually happen when the button is pressed.

iDecideViewController.m

#import <UIKit/UIKit.h>
 @interface iDecideViewController :  UIViewController {
       IBOutlet UILabel *decisionText;
 }
 @property (retain, nonatomic) UILabel *decisionText;
 -(IBAction)buttonPressed:(id)sender;
 @end

We'll need to change the label text to provide Mike's answer, so we need to be able to get to the label control that the framework will build from our nib.

We'll talk more about properties later in the book.

Here's the action that will be called when the button is pressed.

iDecideViewController.h

The @synthesize tells the compiler to create the property we declared in the header file.

#import "iDecideViewController.h"
 @implementation iDecideViewController
 @synthesize decisionText;
 -(IBAction)buttonPressed:(id)sender
 {
    decisionText.text = @"Go for it!";
 }

- (void)dealloc {
    [decisionText release];
    [super dealloc];
 }

This is the implementation of the method that gets called when the button is pressed.

We'll use our reference to the label to change the text.

The dealloc method is where you can clean up your memory usage. We'll talk more about this in Chapter 3.

iDecideViewController.m

What happened?

The Objective-C code is all set to handle it when the button is pressed, but Interface Builder has no idea it needs to connect the button to that code. We can use Interface Builder to hook up our button to the buttonPressed method we just wrote. Then, when the .xib file is loaded by the framework, it will connect the button object it creates with our code.

This is the part we're missing – the link between the instantiated button and the code that needs to get called...

.xib

iDecideViewController.xib

-(IBAction)
buttonPressed:(id)
sender;

Button

-(IBAction)
 buttonPressed:(id)
 sender
 {
 method that the button
 calls
 }

iDecideViewController.h

.h

.m

iDecideViewController.m

Unless the UI components are hooked up to the code, nothing is going to happen.

We need to connect the button's "Hey, I just got pressed" event to our buttonPressed action method. That will get our method called when the user taps on the button. We then need to get a reference to the UILabel that the framework is going to create for us when the nib is loaded—that's where the IBOutlet comes in. Let's start with the outlet so we can change the UILabel text when the button is pressed.

Use Interface Builder to connect UI controls to code

Jump back into Interface Builder for iDecideViewController.xib, and let's hook up the components to our new code.

Hit this button to display the hierarchy view; it's a little easier to see what's going on with the nib.

A list of everything in your view, plus its class name.

If you don't have a two button mouse, just hit CTRL and then click.

❶ Right-click on the label you dropped on the button. This will bring up a list of events and references.

❷ Click on the circle next to New Referencing Outlet and drag it to File's Owner (this represents the class file that will load this nib—in our case, iDecideViewController). Then click on the decisionText outlet. Now when the decisionText UILabel is generated, our decisionText property will be set to a reference to the control, thanks to the IBOutlet.

Ok—I get how we can now change the label, but how does interface builder know that you pressed a button?

Interface Builder lists which events a component can trigger

We need to attach the right component event to the code. We wrote an action method earlier that we can connect the button to:

- (IBAction) buttonPressed:(id)sender;

IB = Interface Builder

This is the name of the method that will get called. The name can be anything, but the method must have one argument of type (id).

All IBAction messages take one argument: the sender of the message. This is the element that triggered the action.

Now we need to pick the event that should trigger this method. If you right-click on the button in Interface Builder, you'll see a list of events it could dispatch. We want the TouchUpInside event.

This list shows all of the events that the button can register. We'll get into the different events later in the book.

Most of these events sound like what they are.

We'll be using the "touch up inside" event.

Elements dispatch events when things happen to them

Whenever something happens to an element, for instance, a button gets tapped, the element dispatches one or more events. What we need to do is tell the button to notify us when that event gets raised. We'll be using the TouchUpInside event. If you think about how you click a button on the iPhone, the actual click inside the button isn't what matters: it's when you remove your finger (touch up) that the actual tap occurs. Connecting an event to a method is just like connecting an element to an outlet.

Connect your events to methods

Just like with outlets, you drag the connection from the button event to File's Owner and select the action that should be called.

❶ Right-click on the button you dropped on the view. This will bring up a list of events and references like it did with the label.

❷ Next click on the circle next to Touch Up Inside and drag it to File's Owner. Click on the buttonPressed action. Now when the button gets pressed, our buttonPressed method will be called.

So does it really matter whether I use an IBOutlet or an IBAction since Interface Builder can use both?

It matters a lot!

They're not the same. Use an IBOutlet when you need a reference to something in the interface (e.g., so you can change the label text). Use an IBAction when you want a control to tell your code when something happens (like the button gets pressed).

Phew. Now I know what to do!

Mike can make at least one decision.

Your app is working! All the pieces are fitting together: the *.xib file describes the interface, Interface Builder has connected it to the code, and Objective-C is making it all work together.

You're on your way to being #1 on the App Store.

How about a Twitter app?

there are no: Dumb Questions

Q:

What is that File's Owner thing?

A:

Interface Builder has an expectation of what class will be the nib's File's Owner. You can change what class Interface Builder thinks it will be, but by default a new project is set up so that the main View Controller created by Xcode is the File's Owner for the main view created by Xcode. That's why we didn't have to change anything. Since the File's Owner is set up to be our iDecideViewController, Interface Builder could look at the iDecideViewController header and see we had an IBOutlet named descriptionText and an IBAction named button pressed. When you connected the UILabel's referencing outlet to File's Owner descriptionText, Interface Builder saved the information necessary so that when the nib is loaded by the application, the references are set correctly in our iDecideViewController. The same thing happened with the TouchUpInside event, except in this case instead of hooking up a component to a reference, it hooked up a component's event to a method that should be called.

Beware—Interface Builder's expectation of the class that will load the nib does not mean that other classes can't try—it just might not work well if that class doesn't have the necessary properties and methods.

Q:

What's with the "Outlet" stuff?

A:

Interface Builder has the idea of Outlets and Actions, and we'll talk more about them in a bit. Basically an Outlet is a reference to something and an Action is a message (method) that gets sent (called) when something happens.

Q:

Why does our new text string have an @ in front of it?

A:

Cocoa Touch uses a string class named NSString for its text strings. Since it's so common, Objective-C has built in support for creating them from constants. You indicate a string constant should be an NSString by putting an @ symbol in front of it. Otherwise, it's just a normal char* like in C or C++.

Your iPhone Toolbox

Get Head First iPhone Development now with the O’Reilly learning platform.

O’Reilly members experience books, live events, courses curated by job role, and more from O’Reilly and nearly 200 top publishers.