Beginning Professional iPhone App Development

Christina Moulton, Teak Mobile Inc.

@ChristinaMltn, christina@teakmobile.com

KW iOS Training

About Me

Christina Moulton

Freelance iOS dev

Suffered through crappy syntax you won't need to bother with

What will I learn?

How to create basic native iOS apps from scratch without wasting a ton of time trying to work against the tools and the language.

Issues that stop people from learning iOS development on their own

What will I NOT learn?

Game programming

Everything

Why iOS?

App Store revenues: $5B im 2012

Employment & contract opportunities

Something different

Getting to know you: Why? What's your background?

Why native apps?

Speed

Ease of UI development & hardware integration

Richer UX

Earlier access to all device features

Easier persistence and offline operation

More later (time permitting)

What stops devs from getting in to iOS?

Syntax

Design patterns

Interface Builder

Apple's web-based tools

Schedule

Session 1: Design Patterns & Obj-C Features, Apple's Tools, SDK & Core Classes

Exercise 1: Interface Builder, IBOutlets & IBActions

Exercise 2: Tableviews, datasources & delegates

Lunch

Session 2: iOS App Ecosystem, 3rd Party Tools & Testing, Key Resources

(Storyboards & UI Components)

Exercise 3: JSON REST APIs & Storyboards

Session 3: Code Signing, App Store Submission, What Should Be a Native App vs. Web App

Time permitting: In App Purchase, Autolayout

What You'll Need

  • Mac running OS X
  • Xcode 5 (4 is ok)
  • Wifi
  • (Optional: iOS Device running at least iOS 6)

Session 1:

Design patterns & language features:

  • Delegate Pattern
  • Blocks (Closures)
  • Categories
  • Objective-C Memory Management
  • Message Sending Model

Apple’s Tools: Xcode, Interface Builder

iOS SDK Frameworks & Core Classes

iOS Background

Objective-C + SDK

UI: Direct Manipulation & Multi-Touch

Just released iOS 7

Objective-C: Syntax

Class Header (.h)

#import "AnyOtherHeaderFile.h"
@interface MyClass : SuperClass { 
  // declare instance variables 
  // (optional)
  NSInteger _myInteger;
} 

// define properties 
@property (nonatomic, strong) NSString *myString;
// define methods
- (anytype)doIt;
- (anytype)doItWithA:(anytype)a; 
- (anytype)doItWithA:(anytype)a andB:(anytype)b; 
+ (anytype)classDoIt;

@end

Cheatsheet from RayWenderlich.com

Objective-C: Syntax

Class Implementation (.m)

#import "MyClass.h" 
 
@implementation MyClass
// implement methods (including custom inits)
- (id)init
{
  self = [super init];
  if (self) { // initialize ivars
  }
  return self;
}
- (anytype)doItWithA:(anytype)a andB:(anytype)b;
{
  NSLog(@"Doing it with %@ and %@", a, b);
  return a;
}
@end

Objective-C: Classes

Messaging:

[receiver message];
[receiver messageWithParameter:aParameter];

Create an Instance of a Class & Call Methods

MyClass *myObject = [[MyClass alloc] init];

[myObject doIt];

id returnValue = [myObject doItWithA:anA andB:aB];

[MyClass classDoIt];

Objective-C: Variables

anyType myVariable;
NSInteger anInteger;
NSObject *anObject;
id anotherObject;

Common Types

int (NSInteger), float, double

BOOL: YES, NO, TRUE, FALSE

ClassName *: e.g., NSString *, NSArray *

id: Ref to any object (NSObject * or subclass)

Objective-C: Properties

myObject.myString = @"a String";
[myObject setMyString:@"a String"];
aString = myObject.myString;
aString = [myObject myString];

Compile-time autosynthesis since Xcode 4.4

Objective-C: Properties

Qualifiers in declaration

@property (nonatomic, strong) aType aProperty;

ARC: strong, weak

Primitives: assign, copy

Threading: nonatomic, atomic

Accessors: readwrite, readonly

Objective-C: NSString

NSString *catOne = @"Mittens"; 
NSString *catTwo = @"Mr. Bigglesworth"; 
NSString *statement = [NSString stringWithFormat: 
  @"The cats to be worshipped are %@ and %@", 
  catOne, catTwo]; 
NSLog(@"%@", statement);
NSString *tipString = @"24.99"; 
float tipFloat = [tipString floatValue];

Also NSMutableString

Objective-C: NSArray

NSMutableArray *array = [NSMutableArray arrayWithObjects: 
   catOne, catTwo, nil]; 
[array addObject:@"Sylvester"];
NSString *sylvester = [array objectAtIndex:2];
NSLog(@"That cat's name is: %@", sylvester);
NSLog(@"%d cats!", array.count); 

for (NSString *cat in array) { 
  NSLog(@"Cat: %@", cat); 
}
// Xcode 4.4+ alt: array[2] 
NSArray *anArray = @[@"John", @"Jane", "Waldo"];
NSString *waldo = anArray[2];

Also NSMutableArray, NSSet, NSDictionary

Objective-C: Blocks (Closures)

Encapsulated chunks of code

int multiplier = 7;
int (^myBlock)(int) = ^(int num) {
    return num * multiplier;
};
NSLog(@"%d", myBlock(3)); // prints 21
multiplier = 8;
NSLog(@"%d", myBlock(3)); // still prints 21
[UIView animateWithDuration:2.0
  animations:^ {
    self.view.alpha = 1.0;
    self.view.frame = CGRectMake(0, 0, 72, 96);
  }
];

iOS Design Patterns

MVC

Singleton

Protocol & Delegate

Decorator: Category

Observer

MVC

Model: Data Model Objects

View: UIView & subclasses

Controller: UIViewController & subclasses

Model <-> Controller <-> View

Seldom code views

(E.g., UITableView)

Singleton

AppDelegate, NSUserDefaults, NSFileManager

Common for resources: Reachability, Location Services, Logging, ...

Thread-safe access

+ (MySingleton *)sharedInstance
{
  static dispatch_once_t once;
  static MySingleton * sharedInstance;
  dispatch_once(&once, ^{
    sharedInstance = [[self alloc] init];
  });
  return sharedInstance;
}

Protocol / Delegate

Common in UIKit classes, e.g., UITableView Datasource & Delegate

Datasource is a specific type of delegate

Configuration & composition over inheritance

@protocol InfoDelegate
- (void)showAppShareView;
- (void)restartTour;
@optional
- (void)optionalMethod;
@end

@interface InfoViewController: UIViewController
@property (nonatomic, strong) id<InfoDelegate> delegate;
@end

Category (Decorator)

Extend a class with additional methods

Included at compile time

@interface ClassToAddMethodsTo (category)
  // ...methods go here
@end
@interface NSString (MD5)
- (NSString *)MD5Hash;
@end

No new ivars

Observer

KVO: Key-Value Observing

Controller can observe Model for changes

Register for notifications

[[NSNotificationCenter defaultCenter] addObserver:self 
						  	selector:@selector(keyboardDidShow:) 
						  	name:UIKeyboardDidShowNotification 
						  	object:nil];
- (void)keyboardDidShow:(NSNotification *)aNotification
{
	// ...
}

Memory Management

The old way: Reference Counting

Need it?

[anObject retain];

Done with it?

[anObject release];

Dealloc'd when release count reaches 0

Autorelease

Return it without retaining it, but don't dealloc until caller is done with it

- (id)myMethod {
  return [[[MyObject alloc] init] autorelease];
}

- (void)someOtherMethod {
  id instance = [obj myMethod];
  // not dealloc'd until after this method returns
}

Automatic Reference Counting (ARC)

Retain/release calls inserted by compiler

No reason not to use (iOS 5.0+)

Qualifiers:

Strong: Owns it

Weak: Non-owning reference (e.g., to parent). Set to nil when no strong references to object exist

Unsafe unretained: Non-owning reference. Not set to nil (dangling pointers)

Autoreleasing: Passed by reference and autoreleased on return

Automatic Reference Counting (ARC)

Consider object graph: Leaks if retain cycles

@interface ClassA
@property (nonatomic, strong) ClassB *objectB;
@end

@interface ClassB
@property (nonatomic, strong) ClassA *objectA;
@end
@interface ClassA
@property (nonatomic, strong) ClassB *objectB;
@end

@interface ClassB
@property (nonatomic, weak) ClassA *objectA;
@end

Apple's Tools

Xcode

Interface Builder

iOS Simulator

Instruments

iOS Projects: .xcodeproj

Xcode windows

iOS Projects: Files

Project settings & .plist

main.m

-Prefix.pch

AppDelegate

.xib

.storyboard

.xcassets

Tests

Live Demo

iOS Projects: Build & Run

Simulator: Hardware

Connecting UI to Code

@property (nonatomic, weak) IBOutlet UIButton *myButton;
- (IBAction)myAction:(id)sender;

Exercise 1: Tap Counter

Create a project with a button and a label

Add an integer property or ivar to track counts

Tapping on the button should change the label text (label.text) to display the number of times the button has been pressed

([NSString stringWithFormat:@"Taps: %d", self.tapCount])

Challenges:

Add a clear count button to restart

Change to a shake or swipe gesture counter

Connecting UI to Code

@property (nonatomic, weak) IBOutlet UIButton *counterButton;
@property (nonatomic, weak) IBOutlet UILabel *counterLabel;
@property (nonatomic) NSInteger tapCount;
- (IBAction)incrementAndUpdateCount:(id)sender
{
  self.tapCount++;
  self.counterLabel.text = [NSString stringWithFormat:@"Taps: %d", 
                            self.tapCount];
}

Key Classes: iOS Technologies

Keyboard & input views

Multitasking

Social media & Sharing

In-App purchase

Game center

Notifications: Push & local

iAd

AirPrint

Location Services

Sound

Accessibility

Edit menu

Undo: buttons & shaking

iCloud

Passbook

Resources

Ray Wenderlich iPhone Tutorials

Apple Mobile Human Interface Guidelines

Questions?

Christina Moulton, Teak Mobile Inc.

@ChristinaMltn, christina@teakmobile.com

KW iOS Training