Beruflich Dokumente
Kultur Dokumente
Over the past two years I have thought long and hard about what you need to know to
really get iPhone programming. The 7 Pillars of iPhone Development are the essential
things you need to learn to effectively develop iPhone apps. Trying to release an app
without being confident in these things will only be an exercise in frustration.
• C Procedural Programming
• Objective-C Object Oriented Programming
• Cocoa-Touch Model-View-Controller Design Pattern
• Architecture of Real World iPhone Apps
• App Product Development
• Apple's Tools
• Practice, Practice & Practice
Before I go into more detail on each of these items I want to talk a little about how much
time you should expect to spend learning iPhone development. If you do any
programming or detailed technology work now you already know that you never really
stop learning when it comes to technology.
However, you can get to a point where you can build something, test the product and you
know how to get more information on your own. To put things in perspective, when I
learned C# after using Visual Basic for years it took me about 6 weeks. A few months
after that, it took me 3 months to learn how to do iPhone programming. This was
because, for me, iPhone programming was radically different that anything I did before.
This is why I suggest giving yourself at least 3 months to learn iPhone development well
enough to get a simple app finished. If you never programmed before expect to take more
time to really understand how to do this.
Now, let's briefly discuss what each of the 7 pillars of iPhone app development are.
Subscribers to my mailing list can expect to get more detail over the next few days and
months about these topics. If you are reading this and you are not a subscriber point your
browser to http://howtomakeiphoneapps.com and sign up for my mailing list.
C Procedural Programming
The C programming language is one of the most widely used programming languages.
The style of programming used in C is called procedural programming. Procedural
programming is a step by step process of giving a computer instructions. This is the real
Programming 101 stuff that you should start with.
Objective-C Object Oriented Programming
Objective-C is the main programming language used in the iPhone. It is based on C and
often when you are working in Objective-C you are using C techniques. Objective-C is
an object oriented programming language; this means that code is organized into units
that are like models of real world objects. For example, you may construct a model of a
car in Objective-C code that corresponds to a car in the real world.
Cocoa-Touch is a collection of code written by the engineers at Apple that gives iPhone
apps the components that you are used to seeing. You must use both C and Objective-C
to work with Cocoa-Touch components. These components include things like buttons,
tables, sliders, date pickers, image pickers and almost everything that you are used to
seeing.
The Model-View-Controller design pattern is sort of the way of working with the Cocoa-
Touch framework that you will need to learn inside and out to develop apps.
The previous three pillars are the basic technology that you will be using. You will also
need to know how to put everything together in a coherent whole. This is what I mean by
"architecture" of an app. This refers to higher level issues like: where to store data, what
components are responsible for what and so on.
Emphasizing product development means focusing on the perspective customers first and
making an amazing product that they will buy. This is a big topic but essentially you need
to turn your code into something that people desperately want to buy. This process
involves finding a market, finding out what they want, putting a healthy dose of spit and
polish into the product and finding a way of telling your customers about your app.
Apple's Tools
At some point you will need to consult the Apple developer website directly. This is
always the primary source of information although the presentation of information on the
Apple site can be confusing to new programmers. Reading the documentation, header
files and using all the tools that Apple provides with XCode (Interface Builder,
Instruments, more) is something you will need to master.
Chapter 2
Objective-C Objects
Objective-C is an object oriented programming language and you will be spending most
of your time creating and working with objects. To define an object to work with you
simply write out the name of the class and a name that will serve as the local pointer to
the object:
NSNumber *numberObject;
NSNumber is a commonly used class in Objective-C and here our object is named
numberObject. The asterisk is used to indicate that the object name is a pointer.
Messaging Objects
When you need an object to do something in Objective-C you must send it a message. In
other programming languages you may be used to "calling methods" with syntax that
looks something like this:
alert.show();
Objective-C handles this task a little bit differently by using this idea of messages and we
will refer to this process as sending a message instead of calling a method. To
demonstrate this syntax let's stick with the example of an alert that we started with above.
To give some context, an alert is a common user interface element that pops up with a
message for a user to read. In programming languages like dot net or Java you will
probably call a method like "show" to invoke the behavior of alert that shows the
message. To do the same thing with this object in Objective-C you would write this:
[alert show];
The first thing you will notice is that the object and method are surround by square
brackets. This is the trademark Objective-C syntax that people always notice and are
sometimes vexed by. Secondly, check out how the method name is separated from the
object here. In this context, we would refer to this statement as sending the "show"
message to the "alert" object.
Often you will need to send a message that includes one or more parameters. In other
programming languages this could look something like this:
In Objective-C we can do a similar thing, but we also get to include descriptive prefixes
(specified in the class definition) to help us with code documentation. For example, here
is how we would send messages like the ones above:
As you can see the syntax is a bit different and you get a little bit more information. This
appears wordy and confusing to many new Objective-C programmers, but you will get
used to this soon enough (I mean it!).
Before you work with an object in Objective-C you will need to create an local instance
of the object. This process is called instantiating and when you are using Objective-C on
the iPhone you will need to allocate memory as well as create an object. To allocate
memory you send a alloc message to the class itself (you can send messages to both
objects and classes). To create the object itself, you will use a constructor that is
generally prefixed with the word "init" or simply init. Here is how you instantiate an
object (from now on I will be using generalized descriptive words for the various
components in the examples):
Releasing Objects
When using Objective-C on the iPhone you must release objects that you have created
using alloc, new or copy. This has to do with memory management which will be
discussed in the next section. To release an object you simply send the "release" message
to the object.
[myObject release];
Here is the pattern that you will typically follow when using objects in Objective-C:
When you are working with Objective-C on the iPhone you need to manage memory
manually. This is a very detailed and important topic and if memory management is not
done correctly then it could lead to memory leaks or app crashes. Managing iPhone
memory is a simple system called "reference counting".
The idea is that the system will keep track of whether it needs to keep the memory for an
object available based on the number of other components that indicate that they want the
object to stick around. Each component gets to indicate its interest in the object by adding
a reference (sometimes called retain) count to the object. You may add to an object's
reference count by sending the "retain" message to an object. So, if 5 components are
interested in myObject then myObject has a reference count of 5. The system will keep
your object's memory in place as long as the reference count is above 0.
As components no longer need an object to stick around they will remove their interest in
the object by sending a "release" message to the object. Each time a release message is
sent to an object it's reference count goes down by 1. Once the reference count reaches 0
the system may destroy the object and re-use the memory at any time.
While reference counting is a simple system, it does require a lot of attention to detail and
being consistent in how you handle this is very helpful. The most important thing to
remember to do is to release every object that you create with the "alloc" keyword. Every
alloc must be matched with a release.
The other thing you must do is to make sure to match every retain message that you send
to an object to a release message. Once you are finished with an object be sure that the
reference count is 0. If you do this then you can be assured that you will not be wasting
memory.
Do not send messages to objects that have been completely released and have a retain
count of 0. If you do this your app will crash; this is the most common and vexing
problems in app development.
Here is an example of a typical life cycle of an object and it's reference count during each
step:
[myObject retain];
//Reference Count: 2
[myObject retain];
//Reference Count: 3
[myObject release];
//Reference Count: 2
[myObject release];
//Reference Count: 1
[myObject release];
//Reference Count: 0
Once myObject reaches a reference count of 0 at the end the system will destroy the
object and if you attempt to send a message to myObject your app will crash. Notice how
each alloc and retain is matched to a release. If you do not match alloc, new and retain
messages with corresponding release messages you will either leak or crash your app.
Let's move on to some classes and objects that are used frequently in Objective-C. Many
of these come from Foundation which provides foundational programming functionality
(sort of like it sounds). Check out the header files that come with XCode to see
everything you can do with Objective-C. It provides a pretty rich framework.
Moving on to strings: in Objective-C the class you use to work with string is called
NSString and it is used like other objects:
NSString also has functions that will help you compose new strings by gluing other
strings, numbers and objects together using the stringWithFormat function:
NSString comes with a rich feature set so be sure to look up the functions available to
you in the header files.
For the most part you may as well stick to using regular C style integers and doubles
when doing math. Objective-C and C and often used together and working with numbers
using int and double is much easier when doing math. You can use the Objective-C class
NSNumber however when you need to style numbers in a particular way. You will also
be using the C style for typical programming activities such as: looping, if-then logic,
case statements, structs and functions. C Refresher for Integers and Doubles:
int i = 3;
NSLog(@"i = %i", i);
double d = 3.4;
NSLog(@"d = %f", d);
double dPlusi = d + i;
NSLog(@"d + i = %f", dPlusi);
Before we end let's take a look at how to use the object oriented arrays that you have
available from Foundation. Arrays are simply lists of objects and in Objective-C you can
put anything into array and you can even mix and match objects. Here is how you
generally use an array:
//Instantiate an array
NSMutableArray *myArray = [[NSMutableArray alloc] init];
//Add elements to an array
[myArray addObject:@"Element 1"];
[myArray addObject:@"Element 2"];
[myArray addObject:@"Element 3"];
One powerful reason to use arrays is that you can leverage the for-each loop which is a
way of repeating the same action on every object in the array:
Of course, you must release the array object when you are finished (sorry for beating it in
like this but it's important!)
[myArray release];
[NSString stringWithFormat:]
This example uses the stringWithFormat function of the NSString class to build a URL
from the longitude and latitude variables supplied above.
The next important piece of this function is the "openURL" method. This is a common
pattern used by apps that share their functionality. Any iPhone app may register an URL
for other apps to use to open that app. Luckily for us, the Google Maps app recognizes
this URL. When this code executes in your app, your app will close and the Google Maps
app will open up to a map of the Washington Monument.
Now, here is how you do the exact same thing with an address string:
//URL to map address
NSString *url = @"http://maps.google.com/?
q=Constitution+Avenue+Northwest+Washington+DC";
//You can also use the NSNumber class when you need to use
//Cocoa framework functionality. Using numbers this way requires
//you to follow the alloc/init, use, release pattern
NSNumber *ns_number_1 = [[NSNumber alloc] initWithDouble:70.5];
NSLog([ns_number_1 stringValue]);
//You must release the NSNumber object. We wait to do this
//until the end since we need to use this object in the last
//example.
Formatting NSNumber
Typecasting
If you are used to a strongly typed programming language like C# or Java you are
probably used to dealing with type casting. That is, you need to do something to make the
type of the variable explicit so the programming environment knows for sure how to
work with it. This is something that is required for code completion to work.
One place where you may find yourself using type casting is in events that you have
assigned to visual controls. Generally, these methods will take an argument of "id",
which essentially means "any type of object" in Objective-C. The "id" object in these
methods is generally the object that the user touched to fire the event.
Clearly, it will be useful to work with this object directly at times. Here is a method that
demos this:
-(void)doSomething:(id)sender{
UIButton *b = (UIButton *) sender;
b.frame = CGRectMake(b.frame.origin.x,
b.frame.origin.y + 100,
b.frame.size.width,
b.frame.size.height);
}This treats the "sender" object as a button and then moves it 100 pixels down the
screen. The syntax for doing type casting is:
UIButton *b = (UIButton *) sender;
For Loop
Arrays are structures used to hold a list of objects. Sometimes though you may want to
sort the order that the elements appear. Doing this is actually pretty simple once you
know how, essentially you will be using the NSArray sortedArrayUsingSelector method.
For example, if you create an array like so:
NSMutableArray *anArray = [[NSMutableArray alloc] init];
[anArray addObject:@"B"];
[anArray addObject:@"A"];
[anArray addObject:@"C"];and then write out the contents of the array to the log using a
foreach loop the results will look like this:
[Session started at 2009-03-25 16:57:55 -0400.]
2009-03-25 16:57:58.647 TipOfTheWeek[3403:20b] B
2009-03-25 16:57:58.648 TipOfTheWeek[3403:20b] A
2009-03-25 16:57:58.649 TipOfTheWeek[3403:20b] CObviously, the contents of the
array stay in the same order in which they were inserted. What you could do is create
another array, sorted, using the sortedArrayUsingSelector method of NSArray. Here is
how:
NSArray *sortedArray = [anArray
sortedArrayUsingSelector:@selector(caseInsensitiveCompare:)];
The odd (for some anyway) piece of this code is the @selector(caseInsensitiveCompare:)
component of the code. This is a method passed to the function that instructions NSArray
on how to sort the array. At any rate, if you run through the array as before and print out
the results to the log you will get this:
Chapter 3
Cocoa touch
Most of the Cocoa Touch classes are designed to be called directly from your code; you
can subclass these classes to add functionality, but you need to do this far less frequently
in Cocoa Touch than in other languages.
The Cocoa Touch application frameworks contain most of the classes you will use to
develop your first applications. The term comes from Cocoa, the object-oriented
frameworks developed for Mac OS X programming (and NextStep before that), along
with GUI classes uniquely designed for use on a mobile, touch-screen device (hence the
“Touch”).
Cocoa Touch’s Foundation framework includes essential data classes, includes basic
utilities, and establishes some core programming conventions that cannot be expressed by
the Objective-C language alone, such as techniques for managing memory. Nearly all
Cocoa classes inherit from a root class, NSObject defined in Foundation.
Perhaps the first and most important thing to discover in Foundation is its data
management classes, which are used throughout Cocoa instead of the procedural C
equivalents. For example, the traditional C suing, the null-terminated char array, is almost
never used in Cocoa. Instead, you use NSString, which represents not only the character
data but also its encoding: with rich support for Unicode (and the UTF- 8 and UTF- 16
encodings), the NSString makes it easy to handle text in any of the dozens of character
sets on the iPhone.
Cocoa also provides a deep set of collection classes, obviating the need for most uses of
C arrays (or hand-rolled collections, such as linked lists and hashtables). Three classes
are used for collecting Cocoa objects: NSArray for ordered collections of objects. NSSet
for unordered collections, and NSDictionary for mapping key objects to value objects.
These three collections are immutable-once initialized, they can’t be changed. If you
want to add, delete, or otherwise change their contents, use the mutable subclasses
NSMutableArray, NSMutableSet and NSMutableDictionary.
The collections can store only NSObjects. If you have C primitives, you can pass them
around Cocoa with the wrapper classes NSData and NSMutableData, which wrap a byte
buffer, and NSNumber, an object container for any of C’s scalar (numeric) types, such as
int, float, or bool.
Cocoa has a few more specific data classes, including NSURL for URLs (including
file://-style URLs representing items on the local filesystem, though you often use
NSString paths too), and timekeeping classes such as NSDate and NSTimeZone.
The “Touch” part of Cocoa Touch is largely represented by the UIKit framework, also
imported by default in every iPhone application. This framework offers the drawing
model, event handling, application life cycle, and other essentials for a touch-based
application. You’ll largely interact with it through the various user interface component
classes it provides: UIButton, UlTextView, UlTableView, and so on. Between the data
types in Foundation and the UI components in UIKit, Cocoa Touch gives you a great
foundation on which to start coding your application.
Chapter 4
Xcode
Installing Xcode
Running Xcode
Because Xcode depends on many system-level services and includes many programs, it
does not install into the Applications folder. To run Xcode and other tools that come with
the iPhone SDK:
2. Double-click “Developer”
3. Double-click “Applications”
4. Double-click “Xcode”
Xcode's user interface, like most Mac applications, is composed of many windows that
are tied together with the main menu at the top of the screen. The first time Xcode is run,
it will present a welcome screen. These screens can be helpful, but not at the moment.
Close them and we will create your first iPhone project.
4. Navigate to a location where you would like to store your iPhone projects. In the text
box labeled “Save As:” type “HelloWorld”.
5. Click “Save”.
The window you are seeing now is the main IDE program. It has the editor and controls
for the compiler built into it. We will now add the code to create a button and a button
action.
1. Expand the “Classes” group on the left side by clicking on the small triangle next to it.
2. Click on “HelloWorldViewController.m”.
3. Scroll down to the second green code region. This is a code comment showing where
to put your code if you are creating your user interface using code.
4. Highlight the whole comment from the “/*” line to the “*/” line and paste or type the
following code in it's place:
- (void)viewDidLoad {
[super viewDidLoad];
helloButton.center = self.view.center;
[self.view addSubview:helloButton];
- (void) helloButtonPressed:(id)sender {
[(UIButton*)sender setTitle:@"Hello World!" forState:UIControlStateNormal];
Now we have some code written for the compiler to compile and the simulator to run. To
compile your code and start the simulator running your program, press the “Build and
Go” button at the top.
If asked to save your changes, press “Save All”. The simulator will start up and run your
program.
Going Further
There is a lot to learn in the computer programming field, especially when writing for
exciting platforms like the iPhone. The best way to learn to program is find a good book
or tutorial online and experiment, experiment, experiment! For example, try to change the
positioning, font size, or messages on the button. Add other buttons. Experiment with
other controls like UILabel, UIImageView, and UITextField.
Chapter 5
Apple Tools
Xcode IDE
Designed from the ground up to take advantage of Cocoa and the newest Apple
technologies, the Xcode IDE provides you with everything you need, from a professional
editor with code completion and Cocoa refactoring, to Apple-tuned open-source
compilers that take full advantage of your multi-core Mac.
Developing with Xcode is all about keeping you focused. Simply click the green Build
and Go button to start the build, debug, and test cycle. Build errors are displayed within
your source code as Message Bubbles. Once your project is built, the debugger bar
appears in the editor window, and hovering your mouse reveals variable values as Data
Tips. If you are developing for iPhone, Xcode automatically installs your application on
the device and attaches the debugger over USB. Throughout, Xcode keeps your code
front and center.
Interface Builder
Interface Builder makes it simple to prototype a full user interface without writing any
code. Laying out windows, buttons, sliders, and other controls will create a fully-
functioning Mac OS X or iOS user interface. You can then turn that prototype into a real
application, keeping all the interface objects and adding features to them. Xcode works
with Interface Builder in real time so you simply wire up the code you write in Xcode to
the graphical controls within Interface Builder.
You can easily build user interfaces because Cocoa is built using the Model-View-
Controller pattern. In fact, the user interfaces are actually archived Cocoa objects that
require no code generation—Cocoa interface objects are dynamically connected to your
implementation code at runtime. Changes to the user interface do not require you to
recompile your code, and changes to your code do not require you to recompile the user
interface.
Instruments collects data such as disk, memory, or CPU usage in real time, either on your
Mac or remotely from a connected iPhone. The collected data is graphically displayed as
tracks over time, making it easy to pinpoint problem areas, then drill down to the
offending lines of code.
Instruments helps guarantee your gorgeous user interface will be accompanied by equally
impressive responsiveness.