iOS development on 1 page

Welcome to a minimal guide to getting started with iOS development.


How to start developing iOS apps

You'll need the Xcode development environment, which comes on your OS X install CDs or can be downloaded for free from Apple. There are 2 prevalent versions of Xcode right now (3 and 4), with totally different UIs, so be aware of the Xcode version when you're looking at tutorials.

You'll write in the language Objective-C. (If you already know Java or C++ then it's not that hard to pick up.) You'll use an API called Cocoa Touch.

You'll design UIs in Interface Builder, which comes with Xcode.

If you want to test apps without a device, Xcode provides an iPhone and iPad simulator.

If you want to test apps with a device, you either have to enroll in the iOS Developer program or the iOS Developer University program or else do some trickery. The iOS University Developer program is free for universities. The iOS Developer program costs $99/year (but you could share an account with friends).

If you want to submit apps to the App Store, you have to enroll in the iOS Developer program (not the University program).

Where to get information:

  • iOS UI Element Usage Guidelines -- list of built-in UI widgets
  • Apple Developer Class Reference pages (e.g. search for "UIViewController class reference")
    • Companion guide -- additional documentation about this and related classes
    • Related sample code -- examples
    • Tasks -- list of methods (see also the methods of parents classes -- Inherits from)
  • iPhone Application Development course from Stanford -- free course materials with lectures on iTunes U
  • Learn from examples. (There's not always a tutorial.)
  • Learn by experimenting. (There's not always documentation. Try stuff and see what happens.)
  • Learn by asking. (Web searches, Stack Overflow.)

To create an iOS app in Xcode, go to New Project > iOS > Application, pick a template, and see what happens.


Selected tutorials and examples


Example of a view

For most views you create, you'll have 3 files: a .h file, a .m file, and a .xib file (pronounced "zib").

SimpleViewController.xib

SimpleViewController.h

@interface SimpleViewController : UIViewController
{

    NSUInteger count;
}

@property (nonatomic, retain) IBOutlet UILabel *label;

- (IBAction)incrementCount:(id)sender;

@end
  • @interface SimpleViewController -- declares a class called SimpleViewController
  • : UIViewController -- says UIViewController is the parent class of SimpleViewController
  • NSUInteger count; -- declares an instance variable ("ivar") called count
  • @property -- declares an instance variable called label, a getter method called `-label`, and a setter method called `-setLabel:`
  • nonatomic -- has to do with multithreading
  • retain -- has to do with memory management
  • IBOutlet -- says that label can be connected to a label in the xib
  • UILabel * -- says that label is a pointer to an object of class UILabel
  • label -- the name of the property and instance variable
  • IBAction -- says that incrementCount can be connected to a button or other control in the xib; the return type of this method is actually void
  • incrementCount:(id)sender -- declares a method called incrementCount that takes an argument of type id; an IBAction should take 1 argument and it should have type id
  • @end -- end of the @interface

SimpleViewController.m

#import "SimpleViewController.h"

@implementation SimpleViewController

@synthesize label;

- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
    if (self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil])
    {
        count = 0;
    }
    return self;
}

- (void)updateLabel
{
    label.text = [NSString stringWithFormat:@"Tapped %u time(s)", count];
}

- (void)viewDidLoad
{
    [super viewDidLoad];
    [self updateLabel];
}

- (IBAction)incrementCount:(id)sender
{
    ++count;
    [self updateLabel];
}

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

@end

  • #import "SimpleViewController.h" -- tells the compiler where to find the declaration of SimpleViewController
  • @implementation SimpleViewController -- definitions of the SimpleViewController methods start here
  • @synthesize label; -- tells the compiler to automatically generate the instance variable, getter method, and setter method for the label property so you don't have to
  • - (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil -- constructor method; another class can call this method to create an instance (object) of class SimpleViewController
  • - (void)viewDidLoad -- overrides the -viewDidLoad method defined in the parent class, UIViewController; the -viewDidLoad method gets called after the runtime loads the view from the xib
  • - (IBAction)incrementCount:(id)sender -- defines what happens when the button is tapped
  • - (void)dealloc -- has to do with memory management

SimpleViewController.xib connections


  • Outlet label -- connects the UILabel named label in SimpleViewController.h and SimpleViewController.m to the Label in SimpleViewController.xib
  • Received Action incrementCount -- says to call the method named incrementCount in SimpleViewController.h and SimpleViewController.m when the user lifts up their finger after touching the Rounded Rectangle Button
  • Outlet view -- you almost always want File's Owner to be a subclass of UIViewController and to have its view property connected to the top-level view in the xib


Delegates and data sources

A delegate or data source is a protocol (set of methods) that a class can implement to modify the behavior of another class. For example:

  • Your class can implement UITableViewDataSource and UITableViewDelegate to modify the behavior of a UITableView — e.g. set the number of cells in the table, provide cells for the table, react when the user selects a cell.
  • Your class can implement UIPickerViewDataSource and UIPickerViewDelegate to modify the behavior of a UIPickerView — e.g. set the number of components in the picker, set the content of rows in the picker, react when the user picks a row.
  • Your class can implement UITextFieldDelegate to modify the behavior of a UITextField
    e.g. react when the user begins editing the text field, filter text typed in the text field

Example code:

Troubleshooting: If the delegate or data source methods are not getting called, you probably forgot to make your class the delegate or data source. You can either do this in the xib or in the source code. 

Example of making YourClass the delegate for a UITableView:

  • Either: In the xib, click on the table view, go to its connections, and connect its delegate outlet onto YourClass (probably File's Owner).
  • Or: In YourClass.m, usually in the -viewDidLoad method, add the line tableView.delegate = self;. (This assumes YourClass has an IBOutlet called tableView.)

Core Data

Core Data is a nifty way to store data in your app. The data gets stored in a SQLite database — but that's an implementation detail you don't have to worry about. In your source code you access the data through Objective-C classes.

For example, let's say you're developing an app to organize homework assignments. You can create a Course entity and an Assignment entity in Core Data. You'll end up with a Course class and Assignment class in source code, backed by a Course table and Assignment table in the database. Core Data lets you define relationships between entities (e.g. every Assignment must have a Course, and every Course has 0 or more Assignments) and say what happens when an object gets deleted (e.g. if you delete a Course, delete all of its Assignments). Core Data provides a uniform way to save and load data, so you don't have to write custom methods to save Courses or Assignments to file.

Documentation:


iPhone/iPad simulator

The simulator's file system is in ~/Library/Application Support/iPhone Simulator/. There you'll find files saved by your app (including the SQLite database for Core Data).