Design Then Code_ Building iOS Apps From Scratch

25
04/10/12 Design Then Code: Building iOS Apps From Scratch 1/25 designthencode.com/scratch/ Building iOS Apps From Scratch by Mike Rundle Before taking a crack at any Design Then Code project tutorials you'll need some knowledge of Xcode, Objective-C, Cocoa and UIKit. My goal is for this guide to help bridge the gap between having no knowledge of iOS development and having enough to start tackling more interesting projects. Apple provides a number of tools to enable developers to build Mac and iOS apps. To download them, head to the Mac App Store and search for "Xcode". This $4.99 download will give you access to Xcode (the IDE that Mac/iPhone developers use), Interface Builder, the Cocoa Frameworks, tools for testing your apps, and a lot more. To register as an official iOS developer and publish apps to the App Store (not to mention testing your apps on a real device!) it costs $99 per year. Here's a quick overview of the tools Apple provides. Xcode Xcode is an IDE (Integrated Development Environment) used by Mac and iOS developers to build applications. It's not just a code editor: it has a variety of additional goodies baked in like great autocomplete support, static code analysis (it finds bugs in your code before you compile, including memory leaks) and a variety of debugging and performance tools. You could use TextMate or BBEdit and then use command line tools to do the final compilation, but most developers choose to do it all within Xcode. I use Xcode for all app development. Interface Builder Tools

Transcript of Design Then Code_ Building iOS Apps From Scratch

Page 1: Design Then Code_ Building iOS Apps From Scratch

04/10/12 Design Then Code: Building iOS Apps From Scratch

1/25designthencode.com/scratch/

Building iOS Apps From Scratchby Mike Rundle

Before taking a crack at any Design Then Code project tutorials you'll need some

knowledge of Xcode, Objective-C, Cocoa and UIKit. My goal is for this guide to help bridge

the gap between having no knowledge of iOS development and having enough to start

tackling more interesting projects.

Apple provides a number of tools to enable developers to build Mac and iOS apps. To

download them, head to the Mac App Store and search for "Xcode". This $4.99 download

will give you access to Xcode (the IDE that Mac/iPhone developers use), Interface Builder,

the Cocoa Frameworks, tools for testing your apps, and a lot more. To register as an

official iOS developer and publish apps to the App Store (not to mention testing your

apps on a real device!) it costs $99 per year.

Here's a quick overview of the tools Apple provides.

Xcode

Xcode is an IDE (Integrated Development

Environment) used by Mac and iOS developers to

build applications. It's not just a code editor: it has a

variety of additional goodies baked in like great

autocomplete support, static code analysis (it finds

bugs in your code before you compile, including

memory leaks) and a variety of debugging and

performance tools. You could use TextMate or BBEdit

and then use command line tools to do the final

compilation, but most developers choose to do it all

within Xcode. I use Xcode for all app development.

Interface Builder

Tools

Page 2: Design Then Code_ Building iOS Apps From Scratch

04/10/12 Design Then Code: Building iOS Apps From Scratch

2/25designthencode.com/scratch/

Interface Builder is an application that lets you build your interfaces visually. Built-in

objects like buttons, tab bars, sliders and labels can easily be dragged onto your app's

interface and then configured by tweaking the palettes and panels. You can also use

Interface Builder to connect targets and actions (what happens when an interface element

is acted on by a user, and what object handles the action) as well as manipulate controllers

and object bindings.

In my particular development workflow, I prefer not to use Interface Builder, mostly

because I work on custom interface components and those still take a lot of code to get

exactly right. I recommend that new Mac and iPhone developers get acquainted with

Interface Builder, but at the same time still learn the UIKit code that it is generating for

you. I've seen many developers start using Interface Builder and never leave it, so they

never actually learn how to code interfaces from scratch. All Design Then Code tutorials

forego Interface Builder and explain how to write all UI code by hand.

Frameworks

And the most important piece of the puzzle: frameworks. Without frameworks and APIs

developers wouldn't easily be able to create applications that run on Mac OS X or iOS.

Apple provides dozens of frameworks that enable developers to do things like create user

interfaces, write networking code, encrypt important information, draw graphics to the

screen, play audio and video, save data and passwords, take pictures, display webpages

and much more.

The frameworks that Apple provides let you start off with a rich set of commands and

tools upon which to build your applications. Without the various frameworks that Apple

provides, every developer would be reinventing the wheel over and over again. There are

lots of goodies given to you in the various Cocoa frameworks so, many times, an

incredibly complex thing can be accomplished in only a few lines of code. An example of

this is automatically fetching a file on the Internet by its URL, parsing this file, then stuffing

it into a data structure that you can manipulate instantly is just a one-liner!.

These are just the main tools that Apple provides but there are many, many more to

explore and use. Go pick up Xcode from the Mac App Store and start poking around

within your new /Developer directory.

Are you totally new to computer programming? Have never even written any JavaScript?

This tutorial might be tough to swallow. Take a look at the following list of terms and

examples:

Variable — var x = 15;

Function — var name = John.getName();

Introduction To Programming?

Page 3: Design Then Code_ Building iOS Apps From Scratch

04/10/12 Design Then Code: Building iOS Apps From Scratch

3/25designthencode.com/scratch/

Loop — for (var x = 0; x < 10; x++)

Conditional — if (x == 20)

Array — var things = array("dog", "cat");

If any of these are confusing to you, I'd suggest heading to the JavaScript tutorial at

w3schools.com and working through the first few sets of chapters to get a quick feel for

general computer programming constructs. If you're coming from a language that does

not look like C (Lisp, Ruby, etc.) or if you have no C programming knowledge (what's a

header file? what's a struct?), I'd recommend taking a quick read of Scott Stevenson's

excellent C language tutorial and then coming back after your brain is thoroughly

soaked with knowledge.

Now let's talk about Objective-C.

Objective-C is the language that most Mac and iOS developers use to write native

applications. There are alternative ways to write Mac and iOS apps (pure C or C++,

MacRuby, PyObjC, MonoTouch, etc.) but we won't be exploring those avenues here. Apart

from these programming languages, it's also possible to build "apps" that aren't natively

compiled for the platform but are instead websites made to look like a native app but

loaded in a web browser. Those apps can be written using a variety of frameworks but

they're primarily built using web technologies including JavaScript, HTML and CSS.

If you're looking to build mobile websites or web apps then you don't need to learn

Objective-C or Cocoa and probably don't need to go any farther in this tutorial. If you're

looking to learn a new programming language and build native apps for the Mac and iOS,

then this is the place for you!

Objective-C is an object-oriented programming language that is essentially a thin layer on

top of C. It adds Smalltalk-style messaging, runtime reflection, inheritance and many other

things to the C programming language. Its syntax is very unique and may be confusing at

first to seasoned developers used to languages like Ruby or Java. Because Objective-C is a

superset of C, developers can "drop down into" C at any point in their code if they wish.

Many parts of a Mac or iOS application will utilize native C function calls and primitive C

data types right next Objective-C methods and data types.

Classes, Objects & Methods

In case your object-oriented programming fu is rusty (or totally nonexistent) we should

first define what classes, objects and methods are and how they relate to each other in

Objective-C.

Introduction To Objective-C

Page 4: Design Then Code_ Building iOS Apps From Scratch

04/10/12 Design Then Code: Building iOS Apps From Scratch

4/25designthencode.com/scratch/

When working with variables that have anWhen working with variables that have an

explicit, set size at compile time, they're storedexplicit, set size at compile time, they're stored

on the stack. The stack stores local informationon the stack. The stack stores local information

and you can access its data without pointers.and you can access its data without pointers.

Primitive data types (Primitive data types (intint, , charchar, , floatfloat, etc.), etc.)

have a defined, maximum size so they're storedhave a defined, maximum size so they're stored

on the stack.on the stack.

In Obj-C, objects don't have a maximum sizeIn Obj-C, objects don't have a maximum size

(they can grow as much as you need them to) so(they can grow as much as you need them to) so

their memory must be dynamically allocated ontheir memory must be dynamically allocated on

the heap and referenced with pointers. Athe heap and referenced with pointers. A

pointer is an address in memory, and to accesspointer is an address in memory, and to access

what's actually stored in that memory position,what's actually stored in that memory position,

you you dereferencedereference the pointer to get at its the pointer to get at its

contents.contents.

A class is a blueprint that describes the state and behavior of a particular set of objects. It

typically models a concept or a thing from the real world, for example, an Animal. An

Animal class would probably define some variables like the number of legs it has, its

height and weight, and also behaviors, like running, eating and sleeping. An object of a

given class is called an instance of the class. Each new instance you create can have its

own values for the data. You could create 100 instances of the Animal class and set each

one's variables to something different. Methods are behaviors a class possesses, and in

Objective-C, you can call a method directly on the class itself or on an instance of it. These

two types of methods are called class methods and instance methods.

When you want to create a new instance of a class, you have to first allocate and initialize a

block of memory for it on the heap. The heap is memory set aside for dynamic allocation

and in Objective-C all objects live on the heap. All Obj-C objects are pointers to this block

of memory and an asterisk (*) denotes that a variable is a pointer type. Here's an example

of creating an instance of our Animal class.

AnimalAnimal **myAnimal myAnimal == [[[[AnimalAnimal alloc alloc]] init init];];

Let's break this down piece by piece. The first

thing you'll probably notice are the square

brackets. They're everywhere in Objective-C and

they encapsulate method calls. On the left side of

the line we're creating a new Animal* variable

named myAnimal, then, on the right side, we're

doing 2 different method calls (one nested within

the other) and assigning what they return to

myAnimal.

To understand what's going on we need to look at

the method calls from the inside-out. First, we're

calling [Animal alloc] which means we're calling

the class method +alloc directly on the Animal

class. Class methods are preceded with a plus

sign. This method returns a generic object type of id. Then, we call the instance method

-init which initializes the memory, allowing us to actually use this new object. Instance

methods start with a minus sign. Objects in Objective-C aren't fully ready to be used

unless these two steps are taken.

An important concept to understand when working with objects is that if you allocated

memory for it, you're also responsible for letting the runtime know when you're done

using the object so that its memory can be released. An object can be in use in different

parts of an app at once, so Objective-C uses a reference counting system to keep track

Page 5: Design Then Code_ Building iOS Apps From Scratch

04/10/12 Design Then Code: Building iOS Apps From Scratch

5/25designthencode.com/scratch/

Starting in Xcode 4.2, there's a new feature thatStarting in Xcode 4.2, there's a new feature that

Cocoa developers can use called Cocoa developers can use called AutomaticAutomatic

Reference CountingReference Counting (ARC) which takes all the (ARC) which takes all the

effort out of manual memory management. It's aeffort out of manual memory management. It's a

compiler feature which will compiler feature which will automaticallyautomatically add in add in

calls to calls to --releaserelease for you so you don't ever have for you so you don't ever have

to manually release or autorelease any objects.to manually release or autorelease any objects.

It's still important to understand what'sIt's still important to understand what's

happening to your memory behind the scenes,happening to your memory behind the scenes,

but now ARC can make your development timesbut now ARC can make your development times

faster. faster. Read an overview of ARC atRead an overview of ARC at

Apple's websiteApple's website or a full explanation at the or a full explanation at the

Clang LLVM site.Clang LLVM site.

of all this usage.

When an object is first created, the number of

references on the object is one. When an object is

no longer being used, a -release message must

be sent to it, and this decreases the number of

references on the object by one. When the overall

number of references on an object drops to zero ,

the object's memory is freed. If objects that are no

longer being used stay around and occupy

memory some bad things could happen, one of

which is your iOS app is forced to quit because it's

using too many resources. For Mac apps, if an app

takes up more and more memory, it could make

the whole system sluggish. Have you ever left

Photoshop or Safari open for a few days and everything gets bogged down? It's because

the apps are continually using more memory — potentially due to a memory leak — and

there are fewer resources for other running apps. Memory is a precious resource when

developing software so it's important to use it judiciously. For an in-depth look at Cocoa

memory management rules, read Apple's Memory Management Programming

Guide.

Now that we know how to create a fully-formed, fully-functional instance of a class, let's

create a new Airplane object and call some methods on it.

AirplaneAirplane **myAirplane myAirplane == [[[[AirplaneAirplane alloc alloc]] init init];];

[[myAirplane flymyAirplane fly];];

[[myAirplane flyTomyAirplane flyTo:@:@"Austin, TX""Austin, TX"];];

[[myAirplane flyTomyAirplane flyTo:@:@"Dulles Airport""Dulles Airport" landAtTerminal landAtTerminal::33];];

Calling methods on objects in Objective-C has a fairly unique syntax compared to other

languages you may be familiar with, so let's recreate the same calls in Java.

AirplaneAirplane myAirplane myAirplane == newnew AirplaneAirplane();();

myAirplanemyAirplane..flyfly();();

myAirplanemyAirplane..flyToflyTo(("Austin, TX""Austin, TX"););

myAirplanemyAirplane..flyToAndLandAtTerminalflyToAndLandAtTerminal(("Dulles Airport""Dulles Airport",, 33););

Here we're initializing a new Airplane object and then calling 3 different methods on it.

The first, -fly takes in no arguments. The second, -flyTo: takes in one argument. The

third, -flyTo:landAtTerminal: takes in two arguments. The full names of Objective-C

Page 6: Design Then Code_ Building iOS Apps From Scratch

04/10/12 Design Then Code: Building iOS Apps From Scratch

6/25designthencode.com/scratch/

methods include the names of the arguments. Colons in a method name indicate that it

takes an argument, one colon for each argument that it takes. These are instance methods

so a minus sign is included at the beginning of the method name.

Objects don't just have behaviors, they can store data as well. Let's imagine a Car object

and the types of data attributes it could possess:

Model year

Name of manufacturer

Color

Will it turn on?

Let's look at these attributes. First, we have model year. This could be represented by a

numerical year, like 2008. What kind of data is 2008? It's a number, and in Objective-C

that number could be represented in a few different ways:

As a primitive int

As a Foundation framework data type NSInteger

As an instance of the NSNumber class

Choices, choices! Let's talk about what each of these mean. The variable type int comes

from C and is a primitive data type that holds a number with a certain maximum value. An

NSInteger is a special primitive data type from Apple's Foundation framework that is

automatically sized correctly for the current architecture. The third way is an instance of

the NSNumber class that is also defined in Foundation framework. We'll learn more about

Foundation and other Apple frameworks in a bit.

Neither an int nor an NSInteger are objects which means you don't have to worry about

dynamically allocating memory for them since they have a pre-defined size. They get

created on the stack, not the heap, so no pointer is needed to access their contents.

Things like an int, NSInteger, CGFloat, CGPoint, CGRect (and a whole slew of other things

defined in the Foundation Data Types Reference) aren't objects, so no pointer

(asterisk) is needed.

Now let's look at the third example of how we could store the number 2008: as an

NSNumber object.

We can initialize a new NSNumber object like this:

Page 7: Design Then Code_ Building iOS Apps From Scratch

04/10/12 Design Then Code: Building iOS Apps From Scratch

7/25designthencode.com/scratch/

NSNumberNSNumber **year year == [[NSNumberNSNumber numberWithInt numberWithInt::20082008];];

If this is an instance of the NSNumber class, where's +alloc? Where's -init? Well, it turns

out, some objects have convenient class methods that return an object with memory that

you don't have to manage yourself. Since you didn't manually create the memory using

+alloc and -init, you don't have to worry about sending it a -release message when

you're done. Many frequently-used objects defined in Apple's Foundation framework have

these nice constructors. Of course if you want (or need) to manually manage their

memory, we could have also done this:

NSNumberNSNumber **year year == [[[[NSNumberNSNumber alloc alloc]] initWithInt initWithInt::20082008];];

So now we have an instance of the NSNumber class that is wrapped around a regular int of

2008. Why go through the trouble of using an NSNumber object when we could have more

easily used an int or NSInteger? Because some Cocoa classes only make use of other

objects, they simply don't work with primitive types, for example, NSArray. An NSArray is

an object that manages the ordered collection of other objects. If we wanted to use an

NSArray to hold a series of numbers, we'd have to use NSNumber objects because it doesn't

work with primitive data types like int or NSInteger. We could use ints and NSIntegers in

a regular C array, but then we wouldn't get all the great, built-in behaviors that are

defined in the NSArray class.

To initialize our Car object and access its instance variables, we do this:

CarCar **myCar myCar == [[[[CarCar alloc alloc]] init init];];

myCarmyCar..modelYear modelYear == [[NSNumberNSNumber numberWithInt numberWithInt::20082008];];

In this example, modelYear is a @property of the Car class which enables us to use the dot

syntax to access it. We'll get into the specifics of properties and instance variables a bit

later.

Now that we know how to initialize new objects, call methods, and access its instance

variables, let's dive into defining new classes.

Defining An Objective-C Class

To define a new class in Objective-C you must define two things: the class's interface and

its implementation. A class interface tells the compiler about the class's instance variables

and methods so it know what to expect. Like a preview of upcoming attractions. A class

Page 8: Design Then Code_ Building iOS Apps From Scratch

04/10/12 Design Then Code: Building iOS Apps From Scratch

8/25designthencode.com/scratch/

implementation is the actual code and functionality for each method. By convention, a

class interface goes into a .h file and the implementation is in a .m file. For a Car class, the

two files would be Car.h and Car.m.

Here's our Car interface file:

@interface@interface CarCar :: NSObjectNSObject {{

NSNumberNSNumber **modelYearmodelYear;;

NSStringNSString **manufacturerNamemanufacturerName;;

UIColorUIColor **colorcolor;;

BOOLBOOL willTurnOn willTurnOn;;

}}

@property@property ((nonatomicnonatomic,, retain retain)) NSNumberNSNumber **modelYearmodelYear;;

@property@property ((nonatomicnonatomic,, copy copy)) NSStringNSString **manufacturerNamemanufacturerName;;

@property@property ((nonatomicnonatomic,, retain retain)) UIColorUIColor **colorcolor;;

@property@property ((nonatomicnonatomic,, assign assign)) BOOLBOOL willTurnOn willTurnOn;;

-- ((voidvoid))drivedrive;;

-- ((voidvoid))turnRadioToStationturnRadioToStation:(:(NSStringNSString *)*)stationstation;;

-- ((voidvoid))setRadioVolumesetRadioVolume:(:(NSNumberNSNumber *)*)volumevolume;;

-- ((BOOLBOOL))hasNavigationhasNavigation;;

@end@end

Let's go over the Car class interface line by line.

@interface@interface CarCar :: NSObjectNSObject

At the top of our interface file we declare Car to be a subclass of NSObject which is the

root class for most of the Cocoa classes you'll encounter. I like to think about subclassing

as creating a more specialized version of an object. A generic class in Cocoa should be an

NSObject subclass. If you're making a specialized version of a button you might make a

UIButton subclass. Specialized version of a text label? It'd be a UILabel subclass. What if

we wanted to make a specialized version of a Car, say, a convertible? Well, we'd probably

declare a Convertible class which would be a subclass of our Car class, which, as I just

explained, is itself an NSObject subclass.

A subclass gives you the functionality of its parent class and all the other parent classes up

the chain. A Ferrari object is a also a Convertible object which is also a Car object. If you

Page 9: Design Then Code_ Building iOS Apps From Scratch

04/10/12 Design Then Code: Building iOS Apps From Scratch

9/25designthencode.com/scratch/

Another great thing about properties is that ifAnother great thing about properties is that if

you want to keep things really simple, you don'tyou want to keep things really simple, you don't

have to declare them as instance variables athave to declare them as instance variables at

all, you can let the runtime environmentall, you can let the runtime environment

automatically createautomatically create the instance variables as the instance variables as

they're needed. So with that in mind, you couldthey're needed. So with that in mind, you could

skip all instance variable declarations in the skip all instance variable declarations in the CarCar

class and have the first line be simplyclass and have the first line be simply

@interface@interface CarCar :: NSObjectNSObject and skip ahead and skip ahead

to your to your @property@property declarations. This really declarations. This really

saves a lot of time, and lets you not repeatsaves a lot of time, and lets you not repeat

declare all Car objects as having GPS then the Ferrari will as well. Right? Sure, but when

you create a subclass in Objective-C you can choose to add or re-implement functionality

of the parent classes as you see fit. For example, all UIButtons look a certain way, but if

you want to make a totally custom button for your iOS app, you can subclass UIButton and

draw the button's graphics yourself. Your custom code will override the default behavior

in the parent UIButton class.

Next up, the class's instance variables.

@interface@interface CarCar :: NSObjectNSObject {{

NSNumberNSNumber **modelYearmodelYear;;

NSStringNSString **manufacturerNamemanufacturerName;;

UIColorUIColor **colorcolor;;

BOOLBOOL willTurnOn willTurnOn;;

}}

Inside the curly braces, right after the class declaration, you'll find the object's instance

variables. Instance variables are attributes for a specific instance of an object. If you create

3 different Car objects they would each have their own values for these instance variables.

Not all cars have the same color, and not all instances of our Car class will have the same

color instance variable value. Instance variables are declared with the variable type and

the variable's name. Three of these instance variables are objects (see the asterisks?) and

the fourth is a primitive boolean type that can only be either YES or NO.

After the instance variables you'll find a series of @property declarations.

@property@property ((nonatomicnonatomic,, retain retain)) NSNumberNSNumber **modelYearmodelYear;;

@property@property ((nonatomicnonatomic,, copy copy)) NSStringNSString **manufacturerNamemanufacturerName;;

@property@property ((nonatomicnonatomic,, retain retain)) UIColorUIColor **colorcolor;;

@property@property ((nonatomicnonatomic,, assign assign)) BOOLBOOL willTurnOn willTurnOn;;

Properties are an Objective-C 2.0 feature that

allow you quicker, more effortless access to your

instance variables. What these actually do is

configure the getter and setter methods to

access and update these instance variables. For

each instance variable you want to access and

update using dot syntax (car.color,

car.willTurnOn, etc.), you have to declare it as a

@property as well. Before Obj-C properties came

Page 10: Design Then Code_ Building iOS Apps From Scratch

04/10/12 Design Then Code: Building iOS Apps From Scratch

10/25designthencode.com/scratch/

yourself in the code.yourself in the code.along, you'd have to write two methods for each

instance variable to "get" and "set" its value, but

now you can use properties to configure them

automatically, allowing us to use the nifty dot syntax described previously. There are

various ways to configure @properties and rather than go into depth here, you'll find

Apple has a guide just for them.

And finally you'll see the method signatures for the behaviors implemented in the .m file.

-- ((voidvoid))drivedrive;;

-- ((voidvoid))turnRadioToStationturnRadioToStation:(:(NSStringNSString *)*)stationstation;;

-- ((voidvoid))setRadioVolumesetRadioVolume:(:(NSNumberNSNumber *)*)volumevolume;;

-- ((BOOLBOOL))hasNavigationhasNavigation;;

These method declarations describe the type of data returned by a method, the method

name and its arguments. These are all instance methods because of the - preceding each

one. These must match their corresponding implementation (the code that actually runs

when the method is called) in the .m file exactly.

Now for the implementation of our Car class which will exist in a file called Car.m.

@implementation@implementation CarCar

@synthesize@synthesize modelYear modelYear,, manufacturerName manufacturerName,, color color,, willTurnOn willTurnOn;;

-- ((voidvoid))drive drive {{

// Code to make the car drive would go here!// Code to make the car drive would go here!

}}

-- ((voidvoid))turnRadioToStationturnRadioToStation:(:(NSStringNSString *)*)station station {{

// Turn on the radio adjust the station!// Turn on the radio adjust the station!

}}

-- ((voidvoid))setRadioVolumesetRadioVolume:(:(NSNumberNSNumber *)*)volume volume {{

// This one goes to 11!// This one goes to 11!

}}

-- ((BOOLBOOL))hasNavigation hasNavigation {{

// Does this car have it?// Does this car have it?

}}

@end@end

Page 11: Design Then Code_ Building iOS Apps From Scratch

04/10/12 Design Then Code: Building iOS Apps From Scratch

11/25designthencode.com/scratch/

Again, let's go over each line.

@implementation@implementation CarCar

At the top is a compiler directive of @implementation which signifies the start of our

implementation file for this class.

@synthesize@synthesize modelYear modelYear,, manufacturerName manufacturerName,, color color,, willTurnOn willTurnOn;;

Next is the @synthesize statement which is the counterpart to @property in the class

interface. In our interface we declared our object's properties, and now, in the

implementation file, we use @synthesize to automatically generate the getters and setters

based on our declared configurations for them. Don't forget to have both @property and

@synthesize declarations for each property you want to use.

-- ((voidvoid))drive drive {{

// Code to make the car drive would go here!// Code to make the car drive would go here!

}}

-- ((voidvoid))turnRadioToStationturnRadioToStation:(:(NSStringNSString *)*)station station {{

// Turn on the radio adjust the station!// Turn on the radio adjust the station!

}}

-- ((voidvoid))setRadioVolumesetRadioVolume:(:(NSNumberNSNumber *)*)volume volume {{

// This one goes to 11!// This one goes to 11!

}}

-- ((BOOLBOOL))hasNavigation hasNavigation {{

// Does this car have it?// Does this car have it?

}}

After we've synthesized our properties, we will write the code for each of the methods

declared in the interface. The method signature is the same as in the interface file, but the

functionality for each method follows directly after within a pair of curly braces.

And that's it! Our Car class is now fully defined. Let's initialize a new Car object and work

with it a bit.

Page 12: Design Then Code_ Building iOS Apps From Scratch

04/10/12 Design Then Code: Building iOS Apps From Scratch

12/25designthencode.com/scratch/

If you're developing in Xcode 4.2 or later andIf you're developing in Xcode 4.2 or later and

have have Automatic Reference CountingAutomatic Reference Counting turned turned

on, you would skip the on, you would skip the --releaserelease message as message as

it's not needed.it's not needed.

CarCar **myCar myCar == [[[[CarCar alloc alloc]] init init];];

// Set some of its properties// Set some of its properties

myCarmyCar..color color == [[UIColorUIColor redColor redColor];];

myCarmyCar..modelYear modelYear == [[NSNumberNSNumber numberWithInt numberWithInt::19951995];];

// Call some of its methods// Call some of its methods

[[myCar turnRadioToStationmyCar turnRadioToStation:@:@"Hot 97""Hot 97"];];

[[myCar drivemyCar drive];];

// Tell the Objective-C runtime that we're done with this Car object// Tell the Objective-C runtime that we're done with this Car object

[[myCar releasemyCar release];];

After creating a fresh instance of a Car object we can start using it. First, we can set some

of its properties like its color or modelYear. The dot notation "object.property" works

because we declared certain instance variables to be able to be retrieved or set in this

manner. It doesn't happen automatically, but if you use @property and @synthesize then

you're golden. It may seem pretty simple, but Objective-C is doing some legwork in the

background to make sure that memory is allocated and deallocated properly when you

directly access an object's properties.

We can also call a Car object's instance methods like -turnRadioToStation: and -drive.

Notice in the first method call, we're passing in a string as an argument since that is

expected from the method definition. The second method, -drive, takes in no arguments.

When we're done using our instance of a Car

class, we send it a -release message to decrease

its reference count by one. As the only place using

this object, the reference count would drop to

zero and its memory would be automatically

deallocated. To be more specific, the runtime

automatically calls the -dealloc method on our Car object. Typically we would implement

-dealloc in this class and do some cleanup/maintenance work before the memory is

deallocated and the object vanishes.

This is just scratching the surface of Objective-C, but it's enough to propel you in the right

direction if you want to start understanding and building Mac and iOS apps.

Now onto the interesting stuff.

Introduction To Cocoa (and Cocoa Touch)

Page 13: Design Then Code_ Building iOS Apps From Scratch

04/10/12 Design Then Code: Building iOS Apps From Scratch

13/25designthencode.com/scratch/

The NS-prefix comes from NeXTSTEP, theThe NS-prefix comes from NeXTSTEP, the

object-oriented operating system developed byobject-oriented operating system developed by

NeXT Computer. Apple purchased NeXT inNeXT Computer. Apple purchased NeXT in

1997 and Mac OS X is a descendant of its1997 and Mac OS X is a descendant of its

operating system.operating system.

It's important to remember that not everythingIt's important to remember that not everything

with an NS-prefix is an object, for example,with an NS-prefix is an object, for example,

NSRectMakeNSRectMake()() is a C function that returns an is a C function that returns an

NSRectNSRect (a type of (a type of structstruct), and ), and NSIntegerNSInteger is a is a

primitive data type.primitive data type.

Depending on which framework you're workingDepending on which framework you're working

with, objects and functions may have a CG-with, objects and functions may have a CG-

prefix (for Core Graphics), a CF-prefix (for Coreprefix (for Core Graphics), a CF-prefix (for Core

Foundation), an MK-prefix (for the iOS mappingFoundation), an MK-prefix (for the iOS mapping

framework MapKit), a UI-prefix (for theframework MapKit), a UI-prefix (for the

interface framework UIKit in iOS), or variousinterface framework UIKit in iOS), or various

others.others.

The phrases "Objective-C development" and "Cocoa development" are thrown around

interchangeably, and usually if you say either one, people know that you're talking about

building Mac and iOS apps.

Cocoa is a set of frameworks that Apple built for developers to use when building Mac and

iOS apps. The Cocoa frameworks are written in Objective-C and Objective-C is the

preferred language used to access the Cocoa frameworks when developing Mac and iOS

applications. Apple used to provide support for using Java to access the Cocoa

frameworks, but it has fallen out of use in recent years. There are other ways to access

Cocoa APIs, including bindings for Python, Perl, Ruby, and C#, but for the most part those

aren't sanctioned by Apple.

The frameworks that make up what's known as

"Cocoa" include Foundation and Application Kit

(AppKit) for Mac OS X, and when developing iOS

apps, Foundation and UIKit. Foundation

framework provides a base layer of classes for

string and number manipulation, date objects,

collections, networking and more. Some objects

include NSString, NSArray, NSURLConnection,

NSDictionary and NSNumber. AppKit classes are

used to build the interface for Mac applications

including windows, controls and menus. Example

AppKit objects include NSWindow, NSView,

NSButton, NSImageView and NSScrollView.

When developing iOS apps you'll still use the

same, more generic classes available in the

Foundation framework but instead of using

AppKit to build user interfaces, UIKit is used instead. Some objects from UIKit that you'll

be using all the time are UIWindow, UIView, UIButton, UIViewController, UILabel,

UITableView, UITextView and UIWebView. You might notice that for many objects, the

UIKit version has the same name as the AppKit original, but with a UI- prefix instead of

NS-. A full list of classes available within UIKit is shown here at Apple's Developer site.

To be honest, you'll probably never use Car or Airplane objects unless you're building an

app for a car dealership or airport. The objects that you'll typically be using and

subclassing are ones that Apple provides as part of the Cocoa frameworks, like NSArray to

manage collections of objects, UIViewController to manage a screenful of content,

UITableViewCell for a custom row in a table, UILabel for displaying small bits of text,

UIImageView to display an image on the screen and many, many more. Apple provides

many interesting and incredibly useful classes for you to use as you construct Mac and iOS

apps, and typically they are descendants of a number of other classes, adding more

functionality and specialization the further down the inheritance chain you look. For

example, let's take a look at UIButton's full inheritance chain:

Page 14: Design Then Code_ Building iOS Apps From Scratch

04/10/12 Design Then Code: Building iOS Apps From Scratch

14/25designthencode.com/scratch/

UIButton inherits from UIControl

UIControl inherits from UIView

UIView inherits from UIResponder

UIResponder inherits from the root class NSObject

NSObject is the root class for most Cocoa objects and handles memory allocation,

initialization, message passing and other lower-level tasks. UIResponder handles

interaction events like tapping the screen with your finger. UIView defines a rectangular

area on the screen and provides the functionality to place or draw content within that

rectangle. UIControl is the base class for user interface widgets and manages the state

(selected? highlighted? disabled?) as well as what actions occur when the user interacts

with it. And finally we get down to UIButton, a specialized control that takes care of a

button's text label, all the styling of the button, and what it looks like when it's selected or

highlighted.

It's important to remember that when using a UIButton you don't just have access to the

functionality of that class, but of all the classes that UIButton inherits from all the way up

to NSObject. I can't tell you how many times I missed something that was available in an

object's parent class because I was only looking in the documentation for the immediate

class I was using.

Common Objects & Functions

Regardless of what your app looks like there are some objects, functions and data

structures that you'll use over and over so it's important to become familiar with them.

NSString

A string is a sequence of characters, and in Objective-C, a string is an NSString object

with a lot of built-in functionality. The shorthand way of referring to a string @"looks

like this" with an @ sign in front of a double-quoted run of characters. NSString

objects can be compared to one another, converted to other encoding formats, used to

hold the contents of a file or URL, changed to C-style strings, used in regular expression

matches or turned into numbers.

Once you create a string it cannot be modified. This may sound odd if you're coming from

PHP or JavaScript, but if you want to modify a string after it has been created, you should

use NSMutableString instead, a mutable (modifiable) subclass of NSString.

Here's an example of how you might construct an NSURL object by using a string:

NSURL NSURL **url url == [[NSURL NSURL URLWithStringURLWithString:@:@"http://google.com/""http://google.com/"];];

Page 15: Design Then Code_ Building iOS Apps From Scratch

04/10/12 Design Then Code: Building iOS Apps From Scratch

15/25designthencode.com/scratch/

A A structstruct is a special C data type that is a special C data type that

encapsulates other pieces of data into a singleencapsulates other pieces of data into a single

cohesive unit. Like an object, but built into C.cohesive unit. Like an object, but built into C.

Many Cocoa objects use Many Cocoa objects use structstructs. Eachs. Each

component of a component of a structstruct is called a member. is called a member.

Some common Some common structstructs you'll need to bes you'll need to be

familiar with include familiar with include NSRangeNSRange (has 2 (has 2

NSUIntegerNSUInteger members: location and length), members: location and length),

CGPointCGPoint (has 2 (has 2 CGFloatCGFloat members: an X members: an X

coordinate and a Y coordinate), coordinate and a Y coordinate), CGSizeCGSize (has 2 (has 2

CGFloatCGFloat members: width and height) and members: width and height) and

CGRectCGRect (has one (has one CGPointCGPoint member and one member and one

CGSizeCGSize member). member).

To access the value of a member within aTo access the value of a member within a

structstruct, dot notation is used. For example, if, dot notation is used. For example, if

myPointmyPoint is an is an CGPointCGPoint, you can access the X, you can access the X

coordinate member of it with coordinate member of it with myPointmyPoint..xx..

And here's an example of using a mutable string:

NSMutableStringNSMutableString **myString myString == [[NSMutableStringNSMutableString stringWithString stringWithString:@:@"Reading""Reading"];];

[[myString replaceOccurrencesOfStringmyString replaceOccurrencesOfString:@:@"Read""Read" withString withString:@:@"Writ""Writ"

options options::NSLiteralSearchNSLiteralSearch range range::NSMakeRangeNSMakeRange((00,, [[myString lengthmyString length])];])];

That's a gigantic method that we're calling! The

NSMutableString instance method

-replaceOccurrencesOfString:

withString:options:range: finds a string within

a string, then replaces it with something else.

Notice the call to the NSMakeRange() function,

part of the Foundation framework. It returns an

NSRange struct data type which has two

members: location and length.

NSArray

An array is an ordered collection of things and if

you're using NSArray, those "things" all have to be

objects. Just like with an NSString, once it's

created it cannot be modified unless you use

NSMutableArray instead. Here's an example of

making an array:

NSArrayNSArray **myArray myArray == [[NSArrayNSArray arrayWithObjects arrayWithObjects:@:@"Fish""Fish",, @@"Dogs""Dogs",, nilnil];];

When creating an NSArray using the +arrayWithObjects: class method, the list of objects

needs to be nil-terminated or it won't compile. It's not very intuitive at first, but it's

important to remember to add it at the end of your list of objects or your code will crash

and burn.

Organizing objects into an array is useless if you never do anything with your new

collection. Here are some examples of what you can do with a filled array.

id myObject id myObject == [[myArray objectAtIndexmyArray objectAtIndex::33];];

[[myArray makeObjectsPerformSelectormyArray makeObjectsPerformSelector::@selector@selector((runTowardsTheMoonrunTowardsTheMoon)];)];

NSUIntegerNSUInteger howMany howMany == [[myArray countmyArray count];];

Page 16: Design Then Code_ Building iOS Apps From Scratch

04/10/12 Design Then Code: Building iOS Apps From Scratch

16/25designthencode.com/scratch/

The -objectAtIndex: instance method returns an id, a generic object in Cocoa. Since you

can hold any type of object you want in an NSArray, when you access an object it gives you

back a generic object type. It doesn't know what types of objects are being stored. Also, in

the second example, what's a @selector? A @selector in Objective-C is basically a

method signature. In this example, we're telling each object in the array to call their

-runTowardsTheMoon instance method. In the third example the method returns an

NSUInteger, a Foundation framework primitive type that's an unsigned integer, that is, an

integer that's greater than zero.

NSDictionary

Almost all languages have the concept of a data structure that holds key-value pairs. Perl

and Ruby have hashes, Python has dictionaries, PHP has associative arrays and Objective-C

has the NSDictionary class. The Foundation framework provides us with NSDictionary

(and its mutable brother NSMutableDictionary) to hold key-value pairs where all keys and

values have to be objects. Let's define some dictionaries:

NSDictionaryNSDictionary **myDict myDict == [[NSDictionaryNSDictionary

dictionaryWithObjectsAndKeys dictionaryWithObjectsAndKeys:@:@"aObj""aObj",, @@"aKey""aKey",, @@"bObj""bObj",, @@"bKey""bKey",, nilnil];];

NSArrayNSArray **objs objs == [[NSArrayNSArray arrayWithObjects arrayWithObjects:@:@"One""One",, @@"Two""Two",, @@"Three""Three",, nilnil];];

NSArrayNSArray **keys keys == [[NSArrayNSArray arrayWithObjects arrayWithObjects:@:@"Blue""Blue",, @@"Green""Green",, @@"Yellow""Yellow",, nilnil];];

NSDictionaryNSDictionary **anotherDict anotherDict == [[NSDictionaryNSDictionary

dictionaryWithObjects dictionaryWithObjects::objs forKeysobjs forKeys::keyskeys];];

In the first example we're calling the class method +dictionaryWithObjectsAndKeys:

which has to be nil-terminated just like with some NSArray methods. In our object listing

at the end we alternate object, key, object, key until we're done with all the pairs.

In the second example we're creating two different NSArray objects — one to hold the

keys and another to hold the objects — and then we pass these two arrays into the

NSDictionary class method +dictionaryWithObjects:forKeys: to build our dictionary.

Again, notice that we're not using +alloc or -init to manually allocate memory for these

dictionaries. This means we don't have to worry about their memory or calling -release

when we're done using them.

A common use of NSDictionary is within an array: each element in the array is an

NSDictionary object. For example, if you're building a Twitter app, the information for

each tweet could sit in an NSDictionary, then each of these dictionaries is kept in order

within an NSArray.

Page 17: Design Then Code_ Building iOS Apps From Scratch

04/10/12 Design Then Code: Building iOS Apps From Scratch

17/25designthencode.com/scratch/

// First, find the dictionary in the 4th position in the array.// First, find the dictionary in the 4th position in the array.

// Then, access the object paired with the key "tweet_text"// Then, access the object paired with the key "tweet_text"

NSStringNSString **status status == [[[[myArray objectAtIndexmyArray objectAtIndex::44]] objectForKey objectForKey:@:@"tweet_text""tweet_text"];];

Organizing NSDictionarys within an NSArray is a simple way to store some structured

data.

NSNumber

If you want to store a primitive number in an NSArray or NSDictionary you'll have to

package it up into an NSNumber object first. NSNumber has a number (ha!) of convenient

class methods so you'll rarely need to manage the memory yourself.

NSNumberNSNumber **myNumber myNumber == [[NSNumberNSNumber numberWithInt numberWithInt::326326];];

intint myInt myInt == [[myNumber intValuemyNumber intValue];];

You can get the primitive value of an NSNumber object just as easily as you can store it.

NSLog()

NSLog() is a C function to send output to the console, useful when debugging your

application.

NSArrayNSArray **myArray myArray == [[NSArrayNSArray arrayWithObjects arrayWithObjects:@:@"Yo""Yo",, @@"Hey""Hey",, nilnil];];

NSLogNSLog(( @@"My array: %@""My array: %@",, myArray myArray ););

intint myInt myInt == 20112011;;

intint anotherInt anotherInt == 20122012;;

NSLogNSLog(( @@"My int: %d and another int: %d""My int: %d and another int: %d",, myInt myInt,, anotherInt anotherInt ););

Writing static text out to your log isn't that useful, so NSLog() lets you output variables as

well. To include a variable in your output, you need to know what type of variable it is

because NSLog() has different format specifiers based on the variable type. For example,

an array is an object so you'd use %@. The specifier for a plain int is %d. These format

specifiers are "stand-ins" for the actual value of the variable listed at the end of the

function call. Apple provides the full list of string format specifiers to be used in NSLog()

so make sure to always use the right one.

Building Cocoa Applications

Page 18: Design Then Code_ Building iOS Apps From Scratch

04/10/12 Design Then Code: Building iOS Apps From Scratch

18/25designthencode.com/scratch/

We've talked about Objective-C syntax and what objects are. We've also discussed some

common Foundation frameworks objects and how Objective-C classes are defined. Now

it's time to start using some more complex Cocoa objects and putting all the pieces

together to build a Cocoa app.

Models, Views and Controllers, Oh My!

A common design pattern in software development is called Model-View-Controller, or

MVC for short. It's a methodology that separates the behavior and data of the application

from the user interface. By keeping parts of the application separated into different classes

your application can be developed more quickly and easily. By their design, the Cocoa

frameworks practically force developers to use solid MVC principles, especially when

building iOS apps.

Each object in your application is assigned one of three roles: model, view or controller.

These roles describe that object's behavior and responsibilities. Let's talk about what each

part of MVC means as it pertains to building iOS apps.

Model

The model layer manages the data of your application. Model objects encapsulate data

and also hold the behaviors that will update or process this data. If you're building a

Twitter app you might create model objects to represent an individual account, tweet,

direct message or follower profile. If you were writing an invoice-sending app you'd

probably have model objects for a company, person, invoice and more. A retro

photography app? Perhaps only one model object representing a photo. You can think of

model objects as being the nouns in a sentence that describes what your app does.

If you were building an app that persistently stores its data across launches, you'd build

behavior into your models so that they could save their own data to a file on the user's

iPhone, or perhaps send it to a server somewhere.

Here's some code showing how you'd initialize and use a model object.

ClientClient **myClient myClient == [[[[ClientClient alloc alloc]] init init];];

myClientmyClient..firstName firstName == @@"John""John";;

myClientmyClient..lastName lastName == @@"Smith""Smith";;

myClientmyClient..phoneNumber phoneNumber == @@"212-555-1212""212-555-1212";;

[[myClient saveDataToFilemyClient saveDataToFile];];

In your apps you may use many model objects or you may use none, it all depends on

what kind of app you're building. Model objects are typically just subclasses of the Cocoa

root object, NSObject.

A benefit of using model objects is that they can be reused. Say you've built an iOS app

Page 19: Design Then Code_ Building iOS Apps From Scratch

04/10/12 Design Then Code: Building iOS Apps From Scratch

19/25designthencode.com/scratch/

and then you choose to port it to the Mac. If you've built your model objects with

reusability in mind (not using iOS-specific APIs) it's fairly easy to port them to another

Cocoa platform like OS X. Your model objects should not be concerned or tied to the user

interface at all, thus making reusability possible.

View

Views are the objects used to build your user interface. For most of this guide the objects

we've discussed represented abstract concepts, things or types of data, but view objects

are different because they're actually seen by the user on the screen. Text labels, buttons,

input fields, table views, scrollable panes and tabs are all view objects with defined

behaviors and attributes. Views in iOS apps are all descendants of UIView, the root object

used to build user interface components defined in the UIKit framework. Here's a list of

all the classes available to you in UIKit.

Views have the ability to draw themselves (with colors, patterns, images, borders,

shadows, corner radii, transparency, etc.) and also respond to user input. Apple provides a

number of built-in view classes for use in your applications. You can use these as-is,

customize some of their attributes, or go completely custom and write your own totally

unique view objects to build custom user interfaces and new methods for user interaction.

Here's an example of initializing and customizing a UILabel, a built-in view object that

draws a simple run of text on the screen.

CGRectCGRect textRect textRect == CGRectMakeCGRectMake((00,,00,,200200,,5050););

UILabelUILabel **myLabel myLabel == [[[[UILabelUILabel alloc alloc]] initWithFrame initWithFrame::textRecttextRect];];

myLabelmyLabel..text text == @@"Photos""Photos";;

myLabelmyLabel..backgroundColor backgroundColor == [[UIColorUIColor clearColor clearColor];];

myLabelmyLabel..font font == [[UIFontUIFont boldSystemFontOfSize boldSystemFontOfSize::2424];];

myLabelmyLabel..textColor textColor == [[UIColorUIColor blackColor blackColor];];

myLabelmyLabel..shadowColor shadowColor == [[UIColorUIColor whiteColor whiteColor];];

That's a lot of properties! You'll find that most Apple-built view objects come loaded with

ways for them to be configured, mostly by setting their properties. Many properties on

UILabel look similar to CSS styles like color, background color, text shadow, font and

more.

An important thing to remember is that initializing a view object does not put it on the

screen, it simply creates the object in memory. To put it on the screen, you must add the

view as a subview on an existing user interface object. The main UIWindow for your

application is the top-level view object for your application. All views that you create and

use in your app are subviews of the window, or of each other, creating an overall view

hierarchy.

Page 20: Design Then Code_ Building iOS Apps From Scratch

04/10/12 Design Then Code: Building iOS Apps From Scratch

20/25designthencode.com/scratch/

Let's take a look at another view object example where we add it to the screen.

CGRectCGRect imageViewRect imageViewRect == CGRectMakeCGRectMake((00,,00,,150150,,150150););

UIImageViewUIImageView **logoView logoView == [[[[UIImageViewUIImageView alloc alloc]] initWithFrame initWithFrame::imageViewRectimageViewRect];];

logoViewlogoView..image image == [[UIImageUIImage imageNamed imageNamed:@:@"logo.png""logo.png"];];

[[selfself..window addSubviewwindow addSubview::logoViewlogoView];];

[[logoView releaselogoView release];]; // Skip this if you're using ARC// Skip this if you're using ARC

When you initialize a view object you typically don't just call -init on it, you call a different

initialization method -initWithFrame which not only initializes the view object but also

sets its frame property. What's a frame? A frame is the rectangular region on the screen

that the view is drawn into. It's a CGRect struct with four members: X position, Y position,

width and height. The X and Y coordinates make up a CGPoint struct named origin, and

the width and height are part of an CGSize struct named size.

In web design, when you absolutely position a <div> or any other block-level element, you

define things like its position and dimensions. A view object is no different. Once a view

object has been added to the overall view hierarchy (either as a subview of the window, or

another view), it then has another property called its bounds. The bounds and frame

properties are very similar in that they both describe the view's position and dimensions,

but the bounds position is {0,0} whereas the frame position is relative to the parent view.

If a 100x100px view object is placed 10px down and 10px from the top left of the parent

view, its frame will be {10,10,100,100} and its bounds will be {0,0,100,100}. This

distinction is important in a few places, mainly when you want to adjust the position of a

view object once it's been placed. You'd do this by modifying its frame, not its bounds.

If you want to completely modify how a built-in interface widget is drawn, you'll want to

create a subclass of it then re-implement its -drawRect: method and fill it with your own

drawing code. Here's an example of how you might implement some custom drawing.

-- ((voidvoid))drawRectdrawRect:(:(CGRectCGRect))rect rect {{

[[[[UIColorUIColor redColor redColor]] setFill setFill];];

UIRectFillUIRectFill((selfself..boundsbounds););

[[[[UIColorUIColor whiteColor whiteColor]] setFill setFill];];

CGRectCGRect thinLine thinLine == CGRectMakeCGRectMake((00,,00,,selfself..boundsbounds..sizesize..widthwidth,, 11););

UIRectFillUIRectFill((thinLinethinLine););

[[[[UIColorUIColor blueColor blueColor]] setFill setFill];];

NSStringNSString **springIsHere springIsHere == @@"Spring Is Here!""Spring Is Here!";;

UIFontUIFont **springFont springFont == [[UIFontUIFont systemFontOfSize systemFontOfSize::2424];];

[[springIsHere drawAtPointspringIsHere drawAtPoint::CGPointMakeCGPointMake((55,,55)) withFont withFont::springFontspringFont];];

Page 21: Design Then Code_ Building iOS Apps From Scratch

04/10/12 Design Then Code: Building iOS Apps From Scratch

21/25designthencode.com/scratch/

}}

Cocoa drawing follows what's called the "painter's model" for imaging. This means that

each successive drawing operation is overlaid on top of the next so the order of your

drawing code is very important. In this example we set the fill color to red and then fill the

entire view's rectangle with that color. After this operation we set the fill color to white and

fill a different rectangle with this new color. The CGRect that we define for the second

drawing operation is a thin line that is 1px tall and spans the width of the entire view

rectangle. It's drawn at {0,0} which is the top left of the view. Finally, we set the fill color

to blue and draw a string at the point {5,5} with a 24px font.

Notice the call to self.bounds.size.width? If we take it step by step, we first make a call

to self.bounds to access the bounds property on this UIView object. This returns a CGRect

struct that, if you'll remember, has two members: origin and size. We then use dot

notation to access the size member which is actually a struct again: an CGSize. Finally,

we access the width member of this final CGSize struct to get the width of this view

object's rectangle on the screen. Trust me, it's a lot more complex to describe it than to

actually use it. You'll be accessing a view's size, position, X coordinate, width, size, etc., in

this fast way all over your code.

This isn't a very exciting example of custom drawing, but in -drawRect: you could overlay

graphics, vector shapes, colors and text any way you choose to implement a particular

design. For interface widgets, a common pattern is to check what interaction state it's in

before drawing to implement different designs for when a user's finger is tapping the

control or other states.

Each view object takes up memory and if you have a very complex interface you may end

up with many, many view objects on the screen and in memory all at once. This may be

fine if you're presenting a fairly static-looking interface, but if you're building a complex

scrollable container or table view, it just won't do at all. One way to get around a multitude

of view objects on screen at once is to use only a few view objects (or just one!) and do all

your text and shape drawing in -drawRect: as it's extremely fast. Instead of placing

UIImageView objects into the view hierarchy, you'd instead draw a UIImage straight to the

screen, and instead of using UILabel, you'd just draw strings directly at a CGPoint or

within an CGRect.

Custom drawing in Cocoa is a very complex subject but it's an essential skill to have when

building custom apps. Take a look at Apple's Introduction To Cocoa Drawing once

you're ready to get dirty.

Controllers

Controllers are the meat of your application. They have many responsibilities and the bulk

of your custom application code will be within controller classes. Here's a sampling of the

Page 22: Design Then Code_ Building iOS Apps From Scratch

04/10/12 Design Then Code: Building iOS Apps From Scratch

22/25designthencode.com/scratch/

responsibilities they have:

Initializing and positioning the view objects for your user interface

Automatically handling rotation changes and necessary layout updates

Handling user events (tapping, swiping, etc.)

Letting model objects know of data changes made at the view layer

Retrieving updated data from model objects and updating the view accordingly

When developing iOS apps, controller objects are subclasses of the root controller class,

UIViewController. Typically, a view controller will manage one screenful of data. If your

iPhone app contains 3 screens of functionality, you'll have a UIViewController subclass

managing each one of them. Take a look at the UIViewController class reference to see

all the methods and properties that it provides.

As mentioned previously, when you write a subclass you're creating a specialized version

of the parent class. By itself, UIViewController isn't very exciting. If you initialize a new

UIViewController object (not your custom subclass) it won't work for you as it expects

you to implement certain behaviors if you want things to happen. It's mainly a blueprint

for you to use to build your own custom controller functionality.

UIViewController objects have a view property which is initialized as the top-level view

object for a single screenful of content. Here's an example of creating this initial view

object within the -loadView method and adding a UIImageView to it.

-- ((voidvoid))loadView loadView {{

CGRectCGRect rect rect == [[UIScreenUIScreen mainScreen mainScreen].].applicationFrameapplicationFrame;;

selfself..view view == [[[[UIViewUIView alloc alloc]] initWithFrame initWithFrame::rectrect];];

UIImageViewUIImageView **imageView imageView == [[[[UIImageViewUIImageView alloc alloc]] initWithFrame initWithFrame::CGRectMakeCGRectMake((55,,55,,200200,,

imageView imageView..image image == [[UIImageUIImage imageNamed imageNamed:@:@"logo""logo"];];

[[selfself..view addSubviewview addSubview::imageViewimageView];];

[[imageView releaseimageView release];]; // Skip this if you're using ARC// Skip this if you're using ARC

}}

The -loadView method in your UIViewController subclass should be implemented when

you are programmatically creating your view hierarchy and not using Interface Builder. It's

called automatically when you first access the view controller's view property (typically

when you add it to the main window object) so there's no need to call it manually.

Page 23: Design Then Code_ Building iOS Apps From Scratch

04/10/12 Design Then Code: Building iOS Apps From Scratch

23/25designthencode.com/scratch/

On the first line we're creating a CGRect to set as our main view's frame. The call to

[UIScreen mainScreen]'s applicationFrame property returns a CGRect representing the

usable section of the screen which is the entire thing, minus the 20px status bar at the

top.

Next, we +alloc and -init our UIView object and set it to self.view which is this

controller's view property. Now that our top-level view object has been initialized, we add

a UIImageView to it as a subview, then release that view.

Let's now add a UIButton object to our view and go over how we handle tap events.

UIButtonUIButton **myButton myButton == [[UIButtonUIButton buttonWithType buttonWithType::UIButtonTypeInfoLightUIButtonTypeInfoLight];];

[[myButton addTargetmyButton addTarget::selfself action action::@selector@selector((wasTappedwasTapped:):) forControlEvents forControlEvents::UIControlEventTouchUpInsideUIControlEventTouchUpInside

[[myButton setFramemyButton setFrame::CGRectMakeCGRectMake((2020,,2020,,2424,,2424)];)];

[[selfself..view addSubviewview addSubview::myButtonmyButton];];

Here we're initializing a UIButton using the convenient class method +buttonWithType

and setting its type to UIButtonTypeInfoLight which is a small info button built into UIKit.

Next, we're calling -addTarget:action:forControlEvents: which is the standard way to

setup a method getting called when a user interaction occurs. It's an instance method on

the UIControl class, a parent class of UIButton. It takes in three arguments: which class

will handle the action (in this case, self), which @selector will be called, and finally, which

interaction event we want to pay attention to. In this example we're listening for

UIControlEventTouchUpInside which is basically a normal tap on an iPhone or iPad

screen. All these event types are listed in the UIControl class reference. All that's left is to

implement the method -wasTapped: in this class and you're in business. Lastly, we set the

button's frame and then add it as a subview on the main view object.

So where do we initialize our view controller and how do we begin using it? Well, if this is

the view controller that will show the main screen of your app, it will be initialized in the

application delegate class which Xcode creates for you when you create a new iOS project.

-- ((BOOLBOOL))applicationapplication:(:(UIApplicationUIApplication *)*)application didFinishLaunchingWithOptionsapplication didFinishLaunchingWithOptions:(:(NSDictionaryNSDictionary

selfself..myViewController myViewController == [[[[MyViewControllerMyViewController alloc alloc]] initWithNibName initWithNibName::nilnil bundle bundle::nilnil

[[selfself..window addSubviewwindow addSubview::selfself..myViewControllermyViewController..viewview];];

[[selfself..myViewControllermyViewController..view releaseview release];]; // Skip this if you're using ARC// Skip this if you're using ARC

[[selfself..window makeKeyAndVisiblewindow makeKeyAndVisible];];

}}

Page 24: Design Then Code_ Building iOS Apps From Scratch

04/10/12 Design Then Code: Building iOS Apps From Scratch

24/25designthencode.com/scratch/

A delegate in Cocoa is a class that you specifyA delegate in Cocoa is a class that you specify

will handle a task for another object. In order towill handle a task for another object. In order to

qualify as a legitimate delegate object, the classqualify as a legitimate delegate object, the class

may need to implement a certain set ofmay need to implement a certain set of

methods that are automatically called. This setmethods that are automatically called. This set

of methods is called a of methods is called a protocolprotocol..

Some complex view objects like Some complex view objects like UITableViewUITableView

use a delegate to handle the creation of tableuse a delegate to handle the creation of table

cells, how many rows it has, and more.cells, how many rows it has, and more.

Typically, a view object's delegate (if it needsTypically, a view object's delegate (if it needs

one) is the view controller it was created within.one) is the view controller it was created within.

Cocoa uses the delegation design patternCocoa uses the delegation design pattern

extensively, and not just for view objects. Theextensively, and not just for view objects. The

reason your application delegate class works isreason your application delegate class works is

because it implements thebecause it implements the

UIApplicationDelegateUIApplicationDelegate protocol to implement protocol to implement

the main lifecycle behaviors of your app.the main lifecycle behaviors of your app.

In our application delegate class, the instance

method -application:

didFinishLaunchingWithOptions: gets called

when the app has successfully finished launching

and is ready to be configured. Here we set

self.myViewController (a property you'd create

on this class) to the newly-created

MyViewController instance, our subclass of

UIViewController. Next, we add its view as a

subview on the main window. It's at this exact

moment that the runtime automatically calls

-loadView on the view controller and our custom

view creation code is executed.

I've only scratched the surface of how controller

objects are used. For a more in-depth look, read

Apple's View Controller Programming Guide.

Your First App

If you haven't already done so, open up Xcode and create a new iOS application. It will

prepare a project for you with some key files already created. One of them is your

application's delegate class which means it handles the main setup of your application. In

this class you'll find -application:didFinishLaunchingWithOptions: which is the jump-

off point for your entire app. Here is where your first code will go, where your first

UIViewController classes will be initialized, where your first model objects may be

created and used.

If you want to get up and running fast with a detailed, step-by-step tutorial, head to the

main Design Then Code site and take a look at the first tutorial for an app called

Texture! It's over 70 pages of text, screenshots and code snippets, including the full

Photoshop file and Xcode project.

Page 25: Design Then Code_ Building iOS Apps From Scratch

04/10/12 Design Then Code: Building iOS Apps From Scratch

25/25designthencode.com/scratch/