24
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 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 Tools

Design Then Code - Building IOS Apps From Scratch

Embed Size (px)

DESCRIPTION

iOS App Development Starter Guide

Citation preview

  • Building iOS Apps From Scratchby Mike Rundle

    Before taking a crack at any Design Then Code project tutorials you'll need someknowledge of Xcode, ObjectiveC, Cocoa and UIKit. My goal is for this guide to help bridgethe gap between having no knowledge of iOS development and having enough to starttackling more interesting projects.

    Apple provides a number of tools to enable developers to build Mac and iOS apps. Todownload them, head to the Mac App Store and search for "Xcode". This $4.99 downloadwill 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 anofficial iOS developer and publish apps to the App Store (not to mention testing yourapps on a real device!) it costs $99 per year.

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

    XcodeXcode is an IDE (Integrated Development Environment) used by Mac and iOS developers tobuild applications. It's not just a code editor: it has a variety of additional goodies baked inlike great autocomplete support, static code analysis (it finds bugs in your code before youcompile, including memory leaks) and a variety of debugging and performance tools. You

    could use TextMate or BBEdit and then use commandline tools to do the final compilation, but mostdevelopers choose to do it all within Xcode. I useXcode for all app development.

    Interface BuilderInterface Builder is an application that lets you buildyour interfaces visually. Builtin objects like buttons,tab bars, sliders and labels can easily be draggedonto your app's interface and then configured bytweaking the palettes and panels. You can also use Interface Builder to connect targets andactions (what happens when an interface element is acted on by a user, and what objecthandles the action) as well as manipulate controllers and object bindings.

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

    Tools

  • because I work on custom interface components and those still take a lot of code to getexactly right. I recommend that new Mac and iPhone developers get acquainted withInterface Builder, but at the same time still learn the UIKit code that it is generating foryou. I've seen many developers start using Interface Builder and never leave it, so theynever actually learn how to code interfaces from scratch. All Design Then Code tutorialsforego Interface Builder and explain how to write all UI code by hand.

    FrameworksAnd the most important piece of the puzzle: frameworks. Without frameworks and APIsdevelopers 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 userinterfaces, write networking code, encrypt important information, draw graphics to thescreen, play audio and video, save data and passwords, take pictures, display webpagesand much more.

    The frameworks that Apple provides let you start off with a rich set of commands andtools upon which to build your applications. Without the various frameworks that Appleprovides, every developer would be reinventing the wheel over and over again. There arelots of goodies given to you in the various Cocoa frameworks so, many times, anincredibly complex thing can be accomplished in only a few lines of code. An example ofthis is automatically fetching a file on the Internet by its URL, parsing this file, thenstuffing it into a data structure that you can manipulate instantly is just a oneliner!.

    These are just the main tools that Apple provides but there are many, many more toexplore and use. Go pick up Xcode from the Mac App Store and start poking around withinyour 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 andexamples:

    Variable var x = 15;

    Function var name = John.getName();

    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

    Introduction To Programming?

  • w3schools.com and working through the first few sets of chapters to get a quick feel forgeneral computer programming constructs. If you're coming from a language that doesnot look like C (Lisp, Ruby, etc.) or if you have no C programming knowledge (what's aheader file? what's a struct?), I'd recommend taking a quick read of Scott Stevenson'sexcellent C language tutorial and then coming back after your brain is thoroughly soakedwith knowledge.

    Now let's talk about ObjectiveC.

    ObjectiveC is the language that most Mac and iOS developers use to write nativeapplications. 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. Apartfrom these programming languages, it's also possible to build "apps" that aren't nativelycompiled for the platform but are instead websites made to look like a native app butloaded in a web browser. Those apps can be written using a variety of frameworks butthey'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 learnObjectiveC or Cocoa and probably don't need to go any farther in this tutorial. If you'relooking to learn a new programming language and build native apps for the Mac and iOS,then this is the place for you!

    ObjectiveC is an objectoriented programming language that is essentially a thin layer ontop of C. It adds Smalltalkstyle messaging, runtime reflection, inheritance and many otherthings to the C programming language. Its syntax is very unique and may be confusing atfirst to seasoned developers used to languages like Ruby or Java. Because ObjectiveC is asuperset 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 Cdata types right next ObjectiveC methods and data types.

    Classes, Objects & MethodsIn case your objectoriented programming fu is rusty (or totally nonexistent) we shouldfirst define what classes, objects and methods are and how they relate to each other inObjectiveC.

    A class is a blueprint that describes the state and behavior of a particular set of objects. Ittypically models a concept or a thing from the real world, for example, an Animal. AnAnimal class would probably define some variables like the number of legs it has, itsheight and weight, and also behaviors, like running, eating and sleeping. An object of agiven class is called an instance of the class. Each new instance you create can have itsown values for the data. You could create 100 instances of the Animal class and set eachone's variables to something different. Methods are behaviors a class possesses, and in

    Introduction To Objective-C

  • When working with variables that have anexplicit, set size at compile time, they're storedon the stack. The stack stores local informationand you can access its data without pointers.Primitive data types (int, char, float, etc.)have a defined, maximum size so they're storedon the stack.

    In ObjC, objects don't have a maximum size(they can grow as much as you need them to)so their memory must be dynamically allocatedon the heap and referenced with pointers. Apointer is an address in memory, and to accesswhat's actually stored in that memory position,you dereference the pointer to get at itscontents.

    Starting in Xcode 4.2, there's a new feature thatCocoa developers can use called AutomaticReference Counting (ARC) which takes all theeffort out of manual memory management. It'sa compiler feature which will automatically addin calls to -release for you so you don't ever

    ObjectiveC, you can call a method directly on the class itself or on an instance of it. Thesetwo 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 initializea block of memory for it on the heap. The heap is memory set aside for dynamic allocationand in ObjectiveC all objects live on the heap. All ObjC objects are pointers to this blockof memory and an asterisk (*) denotes that a variable is a pointer type. Here's an exampleof creating an instance of our Animal class.

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

    Let's break this down piece by piece. The firstthing you'll probably notice are the squarebrackets. They're everywhere in ObjectiveC andthey encapsulate method calls. On the left side ofthe line we're creating a new Animal* variablenamed myAnimal, then, on the right side, we'redoing 2 different method calls (one nested withinthe other) and assigning what they return tomyAnimal.

    To understand what's going on we need to look atthe method calls from the insideout. First, we'recalling [Animal alloc] which means we'recalling the class method +alloc directly on theAnimal class. Class methods are preceded with aplus sign. This method returns a generic object type of id. Then, we call the instancemethod -init which initializes the memory, allowing us to actually use this new object.Instance methods start with a minus sign. Objects in ObjectiveC aren't fully ready to beused unless these two steps are taken.

    An important concept to understand when working with objects is that if you allocatedmemory for it, you're also responsible for letting the runtime know when you're doneusing the object so that its memory can be released. An object can be in use in differentparts of an app at once, so ObjectiveC uses a reference counting system to keep track ofall this usage.

    When an object is first created, the number ofreferences on the object is one. When an object isno longer being used, a -release message mustbe sent to it, and this decreases the number ofreferences on the object by one. When the overallnumber of references on an object drops to zero,

  • have to manually release or autorelease anyobjects. It's still important to understand what'shappening to your memory behind the scenes,but now ARC can make your development timesfaster. Read an overview of ARC at Apple'swebsite or a full explanation at the ClangLLVM site.

    the object's memory is freed. If objects that are nolonger being used stay around and occupymemory some bad things could happen, one ofwhich is your iOS app is forced to quit because it'susing too many resources. For Mac apps, if an apptakes up more and more memory, it could makethe whole system sluggish. Have you ever leftPhotoshop or Safari open for a few days andeverything 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 itjudiciously. For an indepth look at Cocoa memory management rules, read Apple'sMemory Management Programming Guide.

    Now that we know how to create a fullyformed, fullyfunctional instance of a class, let'screate a new Airplane object and call some methods on it.

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

    [myAirplane fly];

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

    [myAirplane flyTo:@"Dulles Airport" landAtTerminal:3];

    Calling methods on objects in ObjectiveC has a fairly unique syntax compared to otherlanguages you may be familiar with, so let's recreate the same calls in Java.

    Airplane myAirplane = new Airplane();

    myAirplane.fly();

    myAirplane.flyTo("Austin, TX");

    myAirplane.flyToAndLandAtTerminal("Dulles Airport", 3);

    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. Thethird, -flyTo:landAtTerminal: takes in two arguments. The full names of ObjectiveCmethods include the names of the arguments. Colons in a method name indicate that ittakes an argument, one colon for each argument that it takes. These are instance methodsso 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 objectand 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 anumerical year, like 2008. What kind of data is 2008? It's a number, and in ObjectiveCthat 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 comesfrom C and is a primitive data type that holds a number with a certain maximum value. AnNSInteger is a special primitive data type from Apple's Foundation framework that isautomatically sized correctly for the current architecture. The third way is an instance ofthe NSNumber class that is also defined in Foundation framework. We'll learn more aboutFoundation and other Apple frameworks in a bit.

    Neither an int nor an NSInteger are objects which means you don't have to worry aboutdynamically allocating memory for them since they have a predefined size. They getcreated 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 otherthings 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 anNSNumber object.

    We can initialize a new NSNumber object like this:

    NSNumber *year = [NSNumber numberWithInt:2008];

    If this is an instance of the NSNumber class, where's +alloc? Where's -init? Well, it turnsout, some objects have convenient class methods that return an object with memory thatyou 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 frequentlyused objects defined in Apple's Foundation framework havethese nice constructors. Of course if you want (or need) to manually manage theirmemory, we could have also done this:

    NSNumber *year = [[NSNumber alloc] initWithInt:2008];

    So now we have an instance of the NSNumber class that is wrapped around a regular int of2008. Why go through the trouble of using an NSNumber object when we could have moreeasily used an int or NSInteger? Because some Cocoa classes only make use of otherobjects, they simply don't work with primitive types, for example, NSArray. An NSArray isan object that manages the ordered collection of other objects. If we wanted to use anNSArray to hold a series of numbers, we'd have to use NSNumber objects because itdoesn't work with primitive data types like int or NSInteger. We could use ints andNSIntegers in a regular C array, but then we wouldn't get all the great, builtin behaviorsthat are defined in the NSArray class.

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

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

    myCar.modelYear = [NSNumber numberWithInt:2008];

    In this example, modelYear is a @property of the Car class which enables us to use thedot syntax to access it. We'll get into the specifics of properties and instance variables abit later.

    Now that we know how to initialize new objects, call methods, and access its instancevariables, let's dive into defining new classes.

    Defining An Objective-C ClassTo define a new class in ObjectiveC you must define two things: the class's interface andits implementation. A class interface tells the compiler about the class's instance variablesand methods so it know what to expect. Like a preview of upcoming attractions. A classimplementation is the actual code and functionality for each method. By convention, aclass 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 Car : NSObject {

  • NSNumber *modelYear;

    NSString *manufacturerName;

    UIColor *color;

    BOOL willTurnOn;

    }

    @property (nonatomic, retain) NSNumber *modelYear;

    @property (nonatomic, copy) NSString *manufacturerName;

    @property (nonatomic, retain) UIColor *color;

    @property (nonatomic, assign) BOOL willTurnOn;

    - (void)drive;

    - (void)turnRadioToStation:(NSString *)station;

    - (void)setRadioVolume:(NSNumber *)volume;

    - (BOOL)hasNavigation;

    @end

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

    @interface Car : NSObject

    At the top of our interface file we declare Car to be a subclass of NSObject which is theroot class for most of the Cocoa classes you'll encounter. I like to think about subclassingas creating a more specialized version of an object. A generic class in Cocoa should be anNSObject subclass. If you're making a specialized version of a button you might make aUIButton subclass. Specialized version of a text label? It'd be a UILabel subclass. What ifwe wanted to make a specialized version of a Car, say, a convertible? Well, we'd probablydeclare a Convertible class which would be a subclass of our Car class, which, as I justexplained, is itself an NSObject subclass.

    A subclass gives you the functionality of its parent class and all the other parent classesup the chain. A Ferrari object is a also a Convertible object which is also a Car object.If you declare all Car objects as having GPS then the Ferrari will as well. Right? Sure, butwhen you create a subclass in ObjectiveC you can choose to add or reimplementfunctionality of the parent classes as you see fit. For example, all UIButtons look a certainway, but if you want to make a totally custom button for your iOS app, you can subclassUIButton and draw the button's graphics yourself. Your custom code will override thedefault behavior in the parent UIButton class.

    Next up, the class's instance variables.

  • Another great thing about properties is that ifyou want to keep things really simple, you don'thave to declare them as instance variables atall, you can let the runtime environmentautomatically create the instance variables asthey're needed. So with that in mind, you couldskip all instance variable declarations in theCar class and have the first line be simply@interface Car : NSObject and skip aheadto your @property declarations. This reallysaves a lot of time, and lets you not repeatyourself in the code.

    @interface Car : NSObject {

    NSNumber *modelYear;

    NSString *manufacturerName;

    UIColor *color;

    BOOL willTurnOn;

    }

    Inside the curly braces, right after the class declaration, you'll find the object's instancevariables. Instance variables are attributes for a specific instance of an object. If you create3 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 samecolor instance variable value. Instance variables are declared with the variable type andthe variable's name. Three of these instance variables are objects (see the asterisks?) andthe 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 (nonatomic, retain) NSNumber *modelYear;

    @property (nonatomic, copy) NSString *manufacturerName;

    @property (nonatomic, retain) UIColor *color;

    @property (nonatomic, assign) BOOL willTurnOn;

    Properties are an ObjectiveC 2.0 feature thatallow you quicker, more effortless access to yourinstance variables. What these actually do isconfigure the getter and setter methods toaccess and update these instance variables. Foreach instance variable you want to access andupdate using dot syntax (car.color,car.willTurnOn, etc.), you have to declare it as a@property as well. Before ObjC properties camealong, you'd have to write two methods for eachinstance variable to "get" and "set" its value, butnow you can use properties to configure themautomatically, allowing us to use the nifty dotsyntax described previously. There are various ways to configure @properties and ratherthan 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.

  • - (void)drive;

    - (void)turnRadioToStation:(NSString *)station;

    - (void)setRadioVolume:(NSNumber *)volume;

    - (BOOL)hasNavigation;

    These method declarations describe the type of data returned by a method, the methodname and its arguments. These are all instance methods because of the preceding eachone. These must match their corresponding implementation (the code that actually runswhen 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 Car

    @synthesize modelYear, manufacturerName, color, willTurnOn;

    - (void)drive {

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

    }

    - (void)turnRadioToStation:(NSString *)station {

    // Turn on the radio adjust the station!

    }

    - (void)setRadioVolume:(NSNumber *)volume {

    // This one goes to 11!

    }

    - (BOOL)hasNavigation {

    // Does this car have it?

    }

    @end

    Again, let's go over each line.

    @implementation Car

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

  • implementation file for this class.

    @synthesize modelYear, manufacturerName, color, willTurnOn;

    Next is the @synthesize statement which is the counterpart to @property in the classinterface. In our interface we declared our object's properties, and now, in theimplementation file, we use @synthesize to automatically generate the getters andsetters based on our declared configurations for them. Don't forget to have both@property and @synthesize declarations for each property you want to use.

    - (void)drive {

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

    }

    - (void)turnRadioToStation:(NSString *)station {

    // Turn on the radio adjust the station!

    }

    - (void)setRadioVolume:(NSNumber *)volume {

    // This one goes to 11!

    }

    - (BOOL)hasNavigation {

    // Does this car have it?

    }

    After we've synthesized our properties, we will write the code for each of the methodsdeclared in the interface. The method signature is the same as in the interface file, but thefunctionality 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 workwith it a bit.

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

    // Set some of its properties

    myCar.color = [UIColor redColor];

    myCar.modelYear = [NSNumber numberWithInt:1995];

    // Call some of its methods

  • If you're developing in Xcode 4.2 or later andhave Automatic Reference Counting turnedon, you would skip the -release message asit's not needed.

    [myCar turnRadioToStation:@"Hot 97"];

    [myCar drive];

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

    [myCar release];

    After creating a fresh instance of a Car object we can start using it. First, we can set someof its properties like its color or modelYear. The dot notation "object.property" worksbecause we declared certain instance variables to be able to be retrieved or set in thismanner. It doesn't happen automatically, but if you use @property and @synthesize thenyou're golden. It may seem pretty simple, but ObjectiveC is doing some legwork in thebackground to make sure that memory is allocated and deallocated properly when youdirectly 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 thatis expected from the method definition. The second method, -drive, takes in noarguments.

    When we're done using our instance of a Carclass, we send it a -release message to decreaseits reference count by one. As the only place usingthis object, the reference count would drop tozero and its memory would be automaticallydeallocated. To be more specific, the runtimeautomatically 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 isdeallocated and the object vanishes.

    This is just scratching the surface of ObjectiveC, but it's enough to propel you in the rightdirection if you want to start understanding and building Mac and iOS apps.

    Now onto the interesting stuff.

    The phrases "ObjectiveC development" and "Cocoa development" are thrown aroundinterchangeably, and usually if you say either one, people know that you're talking aboutbuilding Mac and iOS apps.

    Cocoa is a set of frameworks that Apple built for developers to use when building Mac andiOS apps. The Cocoa frameworks are written in ObjectiveC and ObjectiveC is thepreferred language used to access the Cocoa frameworks when developing Mac and iOS

    Introduction To Cocoa (and Cocoa Touch)

  • The NSprefix comes from NeXTSTEP, theobjectoriented operating system developed byNeXT Computer. Apple purchased NeXT in1997 and Mac OS X is a descendant of itsoperating system.

    It's important to remember that not everythingwith an NSprefix is an object, for example,NSRectMake() is a C function that returns anNSRect (a type of struct), and NSInteger is aprimitive data type.

    Depending on which framework you're workingwith, objects and functions may have a CGprefix (for Core Graphics), a CFprefix (for CoreFoundation), an MKprefix (for the iOS mappingframework MapKit), a UIprefix (for theinterface framework UIKit in iOS), or variousothers.

    applications. Apple used to provide support for using Java to access the Cocoaframeworks, but it has fallen out of use in recent years. There are other ways to accessCocoa APIs, including bindings for Python, Perl, Ruby, and C#, but for the most part thosearen'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 iOSapps, Foundation and UIKit. Foundationframework provides a base layer of classes forstring and number manipulation, date objects,collections, networking and more. Some objectsinclude NSString, NSArray, NSURLConnection,NSDictionary and NSNumber. AppKit classes areused to build the interface for Mac applicationsincluding windows, controls and menus. ExampleAppKit objects include NSWindow, NSView,NSButton, NSImageView and NSScrollView.

    When developing iOS apps you'll still use thesame, more generic classes available in theFoundation framework but instead of usingAppKit to build user interfaces, UIKit is used instead. Some objects from UIKit that you'llbe using all the time are UIWindow, UIView, UIButton, UIViewController, UILabel,UITableView, UITextView and UIWebView. You might notice that for many objects, theUIKit version has the same name as the AppKit original, but with a UI prefix instead ofNS. 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 anapp for a car dealership or airport. The objects that you'll typically be using andsubclassing are ones that Apple provides as part of the Cocoa frameworks, like NSArray tomanage 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 providesmany interesting and incredibly useful classes for you to use as you construct Mac and iOSapps, and typically they are descendants of a number of other classes, adding morefunctionality and specialization the further down the inheritance chain you look. Forexample, let's take a look at UIButton's full inheritance chain:

    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 lowerlevel tasks. UIResponder handlesinteraction events like tapping the screen with your finger. UIView defines a rectangulararea on the screen and provides the functionality to place or draw content within thatrectangle. 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 interactswith it. And finally we get down to UIButton, a specialized control that takes care of abutton's text label, all the styling of the button, and what it looks like when it's selected orhighlighted.

    It's important to remember that when using a UIButton you don't just have access to thefunctionality of that class, but of all the classes that UIButton inherits from all the way upto NSObject. I can't tell you how many times I missed something that was available in anobject's parent class because I was only looking in the documentation for the immediateclass I was using.

    Common Objects & FunctionsRegardless of what your app looks like there are some objects, functions and datastructures that you'll use over and over so it's important to become familiar with them.

    NSStringA string is a sequence of characters, and in ObjectiveC, a string is an NSString objectwith a lot of builtin functionality. The shorthand way of referring to a string @"lookslike this" with an @ sign in front of a doublequoted run of characters. NSStringobjects can be compared to one another, converted to other encoding formats, used tohold the contents of a file or URL, changed to Cstyle strings, used in regular expressionmatches or turned into numbers.

    Once you create a string it cannot be modified. This may sound odd if you're coming fromPHP or JavaScript, but if you want to modify a string after it has been created, you shoulduse 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 *url = [NSURL URLWithString:@"http://google.com/"];

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

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

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

  • A struct is a special C data type thatencapsulates other pieces of data into a singlecohesive unit. Like an object, but built into C.

    Many Cocoa objects use structs. Eachcomponent of a struct is called a member.Some common structs you'll need to befamiliar with include NSRange (has 2NSUInteger members: location and length),CGPoint (has 2 CGFloat members: an Xcoordinate and a Y coordinate), CGSize (has 2CGFloat members: width and height) andCGRect (has one CGPoint member and oneCGSize member).

    To access the value of a member within astruct, dot notation is used. For example, ifmyPoint is an CGPoint, you can access the Xcoordinate member of it with myPoint.x.

    options:NSLiteralSearch range:NSMakeRange(0, [myString length])];

    That's a gigantic method that we're calling! TheNSMutableString instance method -replaceOccurrencesOfString:withString:options:range: finds a stringwithin a string, then replaces it with somethingelse. Notice the call to the NSMakeRange()function, part of the Foundation framework. Itreturns an NSRange struct data type which hastwo members: location and length.

    NSArrayAn array is an ordered collection of things and ifyou're using NSArray, those "things" all have tobe objects. Just like with an NSString, once it'screated it cannot be modified unless you useNSMutableArray instead. Here's an example ofmaking an array:

    NSArray *myArray = [NSArray arrayWithObjects:@"Fish", @"Dogs", nil];

    When creating an NSArray using the +arrayWithObjects: class method, the list ofobjects needs to be nilterminated or it won't compile. It's not very intuitive at first, butit's important to remember to add it at the end of your list of objects or your code willcrash and burn.

    Organizing objects into an array is useless if you never do anything with your newcollection. Here are some examples of what you can do with a filled array.

    id myObject = [myArray objectAtIndex:3];

    [myArray makeObjectsPerformSelector:@selector(runTowardsTheMoon)];

    NSUInteger howMany = [myArray count];

    The -objectAtIndex: instance method returns an id, a generic object in Cocoa. Sinceyou can hold any type of object you want in an NSArray, when you access an object itgives you back a generic object type. It doesn't know what types of objects are beingstored. Also, in the second example, what's a @selector? A @selector in ObjectiveC isbasically a method signature. In this example, we're telling each object in the array to calltheir -runTowardsTheMoon instance method. In the third example the method returns an

  • NSUInteger, a Foundation framework primitive type that's an unsigned integer, that is, aninteger that's greater than zero.

    NSDictionaryAlmost all languages have the concept of a data structure that holds keyvalue pairs. Perland Ruby have hashes, Python has dictionaries, PHP has associative arrays and ObjectiveChas the NSDictionary class. The Foundation framework provides us with NSDictionary(and its mutable brother NSMutableDictionary) to hold keyvalue pairs where all keysand values have to be objects. Let's define some dictionaries:

    NSDictionary *myDict = [NSDictionary

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

    NSArray *objs = [NSArray arrayWithObjects:@"One", @"Two", @"Three", nil];

    NSArray *keys = [NSArray arrayWithObjects:@"Blue", @"Green", @"Yellow", nil];

    NSDictionary *anotherDict = [NSDictionary

    dictionaryWithObjects:objs forKeys:keys];

    In the first example we're calling the class method +dictionaryWithObjectsAndKeys:which has to be nilterminated just like with some NSArray methods. In our object listingat 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 thekeys and another to hold the objects and then we pass these two arrays into theNSDictionary class method +dictionaryWithObjects:forKeys: to build ourdictionary. Again, notice that we're not using +alloc or -init to manually allocatememory for these dictionaries. This means we don't have to worry about their memory orcalling -release when we're done using them.

    A common use of NSDictionary is within an array: each element in the array is anNSDictionary object. For example, if you're building a Twitter app, the information foreach tweet could sit in an NSDictionary, then each of these dictionaries is kept in orderwithin an NSArray.

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

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

    NSString *status = [[myArray objectAtIndex:4] objectForKey:@"tweet_text"];

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

  • NSNumberIf you want to store a primitive number in an NSArray or NSDictionary you'll have topackage it up into an NSNumber object first. NSNumber has a number (ha!) of convenientclass methods so you'll rarely need to manage the memory yourself.

    NSNumber *myNumber = [NSNumber numberWithInt:326];

    int myInt = [myNumber 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 yourapplication.

    NSArray *myArray = [NSArray arrayWithObjects:@"Yo", @"Hey", nil];

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

    int myInt = 2011;

    int anotherInt = 2012;

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

    Writing static text out to your log isn't that useful, so NSLog() lets you output variables aswell. To include a variable in your output, you need to know what type of variable it isbecause 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 formatspecifiers are "standins" for the actual value of the variable listed at the end of thefunction call. Apple provides the full list of string format specifiers to be used in NSLog()so make sure to always use the right one.

    We've talked about ObjectiveC syntax and what objects are. We've also discussed somecommon Foundation frameworks objects and how ObjectiveC classes are defined. Nowit's time to start using some more complex Cocoa objects and putting all the piecestogether to build a Cocoa app.

    Models, Views and Controllers, Oh My!A common design pattern in software development is called ModelViewController, orMVC for short. It's a methodology that separates the behavior and data of the applicationfrom the user interface. By keeping parts of the application separated into different classesyour application can be developed more quickly and easily. By their design, the Cocoa

    Building Cocoa Applications

  • frameworks practically force developers to use solid MVC principles, especially whenbuilding 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 eachpart of MVC means as it pertains to building iOS apps.

    ModelThe model layer manages the data of your application. Model objects encapsulate data andalso hold the behaviors that will update or process this data. If you're building a Twitterapp you might create model objects to represent an individual account, tweet, directmessage or follower profile. If you were writing an invoicesending app you'd probablyhave 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 asbeing 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 buildbehavior into your models so that they could save their own data to a file on the user'siPhone, or perhaps send it to a server somewhere.

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

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

    myClient.firstName = @"John";

    myClient.lastName = @"Smith";

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

    [myClient saveDataToFile];

    In your apps you may use many model objects or you may use none, it all depends onwhat kind of app you're building. Model objects are typically just subclasses of the Cocoaroot object, NSObject.

    A benefit of using model objects is that they can be reused. Say you've built an iOS appand then you choose to port it to the Mac. If you've built your model objects withreusability in mind (not using iOSspecific APIs) it's fairly easy to port them to anotherCocoa platform like OS X. Your model objects should not be concerned or tied to the userinterface at all, thus making reusability possible.

    ViewViews are the objects used to build your user interface. For most of this guide the objectswe've discussed represented abstract concepts, things or types of data, but view objectsare 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 objectused to build user interface components defined in the UIKit framework. Here's a list ofall 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 anumber of builtin view classes for use in your applications. You can use these asis,customize some of their attributes, or go completely custom and write your own totallyunique view objects to build custom user interfaces and new methods for user interaction.

    Here's an example of initializing and customizing a UILabel, a builtin view object thatdraws a simple run of text on the screen.

    CGRect textRect = CGRectMake(0,0,200,50);

    UILabel *myLabel = [[UILabel alloc] initWithFrame:textRect];

    myLabel.text = @"Photos";

    myLabel.backgroundColor = [UIColor clearColor];

    myLabel.font = [UIFont boldSystemFontOfSize:24];

    myLabel.textColor = [UIColor blackColor];

    myLabel.shadowColor = [UIColor whiteColor];

    That's a lot of properties! You'll find that most Applebuilt view objects come loaded withways for them to be configured, mostly by setting their properties. Many properties onUILabel look similar to CSS styles like color, background color, text shadow, font andmore.

    An important thing to remember is that initializing a view object does not put it on thescreen, it simply creates the object in memory. To put it on the screen, you must add theview as a subview on an existing user interface object. The main UIWindow for yourapplication is the toplevel view object for your application. All views that you create anduse in your app are subviews of the window, or of each other, creating an overall viewhierarchy.

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

    CGRect imageViewRect = CGRectMake(0,0,150,150);

    UIImageView *logoView = [[UIImageView alloc] initWithFrame:imageViewRect];

    logoView.image = [UIImage imageNamed:@"logo.png"];

    [self.window addSubview:logoView];

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

  • When you initialize a view object you typically don't just call -init on it, you call adifferent initialization method -initWithFrame which not only initializes the view objectbut also sets its frame property. What's a frame? A frame is the rectangular region on thescreen that the view is drawn into. It's a CGRect struct with four members: X position, Yposition, width and height. The X and Y coordinates make up a CGPoint struct namedorigin, and the width and height are part of an CGSize struct named size.

    In web design, when you absolutely position a or any other blocklevel element,you define things like its position and dimensions. A view object is no different. Once aview object has been added to the overall view hierarchy (either as a subview of thewindow, or another view), it then has another property called its bounds. The bounds andframe properties are very similar in that they both describe the view's position anddimensions, but the bounds position is {0,0} whereas the frame position is relative to theparent view. If a 100x100px view object is placed 10px down and 10px from the top leftof 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 toadjust the position of a view object once it's been placed. You'd do this by modifying itsframe, not its bounds.

    If you want to completely modify how a builtin interface widget is drawn, you'll want tocreate a subclass of it then reimplement its -drawRect: method and fill it with your owndrawing code. Here's an example of how you might implement some custom drawing.

    - (void)drawRect:(CGRect)rect {

    [[UIColor redColor] setFill];

    UIRectFill(self.bounds);

    [[UIColor whiteColor] setFill];

    CGRect thinLine = CGRectMake(0,0,self.bounds.size.width, 1);

    UIRectFill(thinLine);

    [[UIColor blueColor] setFill];

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

    UIFont *springFont = [UIFont systemFontOfSize:24];

    [springIsHere drawAtPoint:CGPointMake(5,5) withFont:springFont];

    }

    Cocoa drawing follows what's called the "painter's model" for imaging. This means thateach successive drawing operation is overlaid on top of the next so the order of yourdrawing code is very important. In this example we set the fill color to red and then fill theentire view's rectangle with that color. After this operation we set the fill color to white andfill a different rectangle with this new color. The CGRect that we define for the seconddrawing 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 colorto 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 acall to self.bounds to access the bounds property on this UIView object. This returns aCGRect struct that, if you'll remember, has two members: origin and size. We thenuse 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 thisview object's rectangle on the screen. Trust me, it's a lot more complex to describe it thanto 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 overlaygraphics, vector shapes, colors and text any way you choose to implement a particulardesign. For interface widgets, a common pattern is to check what interaction state it's inbefore drawing to implement different designs for when a user's finger is tapping thecontrol or other states.

    Each view object takes up memory and if you have a very complex interface you may endup with many, many view objects on the screen and in memory all at once. This may befine if you're presenting a fairly staticlooking interface, but if you're building a complexscrollable container or table view, it just won't do at all. One way to get around a multitudeof view objects on screen at once is to use only a few view objects (or just one!) and do allyour text and shape drawing in -drawRect: as it's extremely fast. Instead of placingUIImageView objects into the view hierarchy, you'd instead draw a UIImage straight to thescreen, and instead of using UILabel, you'd just draw strings directly at a CGPoint orwithin an CGRect.

    Custom drawing in Cocoa is a very complex subject but it's an essential skill to have whenbuilding custom apps. Take a look at Apple's Introduction To Cocoa Drawing once you'reready to get dirty.

    ControllersControllers are the meat of your application. They have many responsibilities and the bulkof your custom application code will be within controller classes. Here's a sampling of theresponsibilities 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 youriPhone app contains 3 screens of functionality, you'll have a UIViewController subclassmanaging each one of them. Take a look at the UIViewController class reference to seeall the methods and properties that it provides.

    As mentioned previously, when you write a subclass you're creating a specialized versionof the parent class. By itself, UIViewController isn't very exciting. If you initialize a newUIViewController object (not your custom subclass) it won't work for you as it expectsyou to implement certain behaviors if you want things to happen. It's mainly a blueprintfor you to use to build your own custom controller functionality.

    UIViewController objects have a view property which is initialized as the toplevel viewobject for a single screenful of content. Here's an example of creating this initial viewobject within the -loadView method and adding a UIImageView to it.

    - (void)loadView {

    CGRect rect = [UIScreen mainScreen].applicationFrame;

    self.view = [[UIView alloc] initWithFrame:rect];

    UIImageView *imageView = [[UIImageView alloc] initWithFrame:CGRectMake(5,5,

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

    [self.view addSubview:imageView];

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

    }

    The -loadView method in your UIViewController subclass should be implementedwhen you are programmatically creating your view hierarchy and not using InterfaceBuilder. 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 itmanually.

    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 representingthe usable section of the screen which is the entire thing, minus the 20px status bar at thetop.

    Next, we +alloc and -init our UIView object and set it to self.view which is thiscontroller's view property. Now that our toplevel view object has been initialized, we adda UIImageView to it as a subview, then release that view.

  • A delegate in Cocoa is a class that you specifywill handle a task for another object. In order toqualify as a legitimate delegate object, the classmay need to implement a certain set ofmethods that are automatically called. This setof methods is called a protocol.

    Some complex view objects like UITableViewuse a delegate to handle the creation of tablecells, how many rows it has, and more.Typically, a view object's delegate (if it needs

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

    UIButton *myButton = [UIButton buttonWithType:UIButtonTypeInfoLight];

    [myButton addTarget:self action:@selector(wasTapped:) forControlEvents:UIControlEventTouchUpInside

    [myButton setFrame:CGRectMake(20,20,24,24)];

    [self.view addSubview:myButton];

    Here we're initializing a UIButton using the convenient class method +buttonWithTypeand setting its type to UIButtonTypeInfoLight which is a small info button built intoUIKit. Next, we're calling -addTarget:action:forControlEvents: which is the standardway to setup a method getting called when a user interaction occurs. It's an instancemethod 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, andfinally, which interaction event we want to pay attention to. In this example we're listeningfor UIControlEventTouchUpInside which is basically a normal tap on an iPhone or iPadscreen. All these event types are listed in the UIControl class reference. All that's left is toimplement the method -wasTapped: in this class and you're in business. Lastly, we set thebutton'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 isthe view controller that will show the main screen of your app, it will be initialized in theapplication delegate class which Xcode creates for you when you create a new iOS project.

    - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(

    self.myViewController = [[MyViewController alloc] initWithNibName:nil bundle

    [self.window addSubview:self.myViewController.view];

    [self.myViewController.view release]; // Skip this if you're using ARC

    [self.window makeKeyAndVisible];

    }

    In our application delegate class, the instancemethod -application:didFinishLaunchingWithOptions: gets calledwhen the app has successfully finished launchingand is ready to be configured. Here we setself.myViewController (a property you'd createon this class) to the newlycreatedMyViewController instance, our subclass ofUIViewController. Next, we add its view as a

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

    Cocoa uses the delegation design patternextensively, and not just for view objects. Thereason your application delegate class works isbecause it implements theUIApplicationDelegate protocol toimplement the main lifecycle behaviors of yourapp.

    subview on the main window. It's at this exactmoment that the runtime automatically calls -loadView on the view controller and our customview creation code is executed.

    I've only scratched the surface of how controllerobjects are used. For a more indepth look, readApple's View Controller Programming Guide.

    Your First AppIf you haven't already done so, open up Xcode and create a new iOS application. It willprepare a project for you with some key files already created. One of them is yourapplication's delegate class which means it handles the main setup of your application. Inthis class you'll find -application:didFinishLaunchingWithOptions: which is thejumpoff point for your entire app. Here is where your first code will go, where your firstUIViewController classes will be initialized, where your first model objects may becreated and used.

    If you want to get up and running fast with a detailed, stepbystep tutorial, head to themain 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 fileand Xcode project.