Pimp My Cat App

Let’s add more features to our cat feeding app from last week to give it more flavour.

Background Image

First let’s add a background image. We want our image to be compatible with Retina-display iPhones, so it should have a resolution of 640 x 960.

  1. Find a suitable image to use.
  2. Resize it in an editing tool like Photoshop and create two versions:
    • Background.jpg at 320 x 480 pixels
    • Background@2x.jpg at 640 x 960 pixels
  3. Drag the images to the Project Navigator (on the left) in Xcode.
  4. Leave the options at their default values and click Finish.
  5. Open the Storyboard and drag a UIImageView to the bottom of the ViewController stack.
  6. In the Attributes Inspector (on the right), set the Image field to Background.jpg.
  7. Set the Alpha to a value near 0.25.

Tidy Code

Let’s add our new initializer to Animal and use it when creating our Cat and Mouse objects.

Header Source

User Defaults

The Foundation framework includes the very useful NSUserDefaults class, which can be used for storing settings and options for your app. It’s basically a type of persistent NSMutableDictionary, meaning that its contents are saved even when you quit the app.

The NSUserDefaults instance used is retrieved using the + (NSUserDefaults *)standardUserDefaults class method.

Values are set using setXXX:forKey: and retrieved using xxxForKey:. Note that you can pass primitive types (like int, float, and BOOL) as values, and that keys must be of type NSString.

The - (BOOL)synchronize method is called to save the changes to disk.

Let’s add user defaults to our app to remember the cat’s weight between different runs of the program.

First, we’ll add a new updateWeight: method to handle any changes to the Cat weight.

We can now store and retrieve the weight from the user defaults.

Text Input

Let’s add a new UI control for setting the Cat name.

First, let’s add the name property to the Cat class.

Header Source

Next, let’s add a UITextField to the view.

  1. Open the Storyboard and drag a UITextField to the top of the ViewController stack.
  2. Connect an outlet to the ViewController.
  3. Connect an action from the “Did End On Exit” event to the ViewController.
  4. In the Attributes Inspector (on the right), set the Placeholder field to Name Your Cat!.

Then, let’s add some code to read the name from the input field.

Header Source

Finally, let’s store and retrieve the name in the user defaults.

Object Typing

Dynamic Binding

All objects are allocated in the heap (in memory), and this is why we always use pointers.

When we give a pointer a type, we say that it is statically typed. In the following example,

aString is a statically typed pointer to an NSString.

id, which we’ve seen before as the return type of - (id)init is a non-statically typed pointer. We could alternatively write the following:

id is useful when the pointer type can vary. This is the case with - (id)init, which is often called by subclasses. This is also the case when using collections like NSArray and NSDictionary because they can hold different types of objects and keys.

Even though it’s perfectly valid to use id anytime, it makes more sense to statically type our pointers, especially when we know their type.

Attempts to call methods on objects always happen at runtime, never at compile time. Static typing allows the compiler to find bugs, and it will generate errors when methods called on objects aren’t found.

Casting and Typing

Let’s look back at our animals.

Header Source


We can find out information on objects before calling methods that might not be valid. This is done using methods defined in the root NSObject class.

- (BOOL)respondsToSelector:(SEL)aSelector
Returns whether or not the object implements or inherits a method that can respond to a specified message.

When referencing selectors, we have to use the @selector(...) directive, which turns the name of a method into a selector.

We can also use the SEL type to create a variable for our selector.

- (BOOL)isKindOfClass:(Class)aClass
Returns whether or not the object is an instance of the given class, or an instance of any class that inherits from it.

- (BOOL)isMemberOfClass:(Class)aClass
Returns whether or not the object is an instance of the given class (excluding its subclasses).

The previous code generates the following output.

Foundation Classes

The Foundation framework is a collection of Objective-C classes. As the name implies, these are very useful primitive classes that will be at the base of most apps you build.

The root class. All classes you will define will inherit from NSObject.

An object wrapper for the primitive number types (int, float, double, BOOL, …).
NSNumber allows you to use primitives wherever an NSObject is required.

The base string class.
NSString is immutable, meaning it cannot be changed once it is created. If you need an editable string, you must use NSMutableString.

An ordered collection of objects, accessible by index. As always, indices start at 0.

NSArray is immutable. If you need a dynamic array, you must use NSMutableArray. This is similar to a Vector in Java.

You can iterate through an NSArray using the for-in syntax.

A collection of objects accessible by key. A key can be any NSObject but must be unique. If you use the same key twice, the first object associated with it will be replaced. This is similar to a Map in Java.

NSDictionary is immutable. If you need a dynamic collection, you must use NSMutableDictionary.

You can also iterate through the keys of an NSDictionary using the for-in syntax.


Instance vs. Class Methods

Instance Class
Method called on an instance of a class, an object. Method called on the class itself, a static method.
A “normal” method, that affects a specific object. Conventially used for object creation and utilities.
Starts with a -, for example:
- (void)addWeight:(double)weightToAdd;
- (id)initWithFormat:(NSString *)format ...
Starts with a +, for example:
+ (id)alloc
+ (id)stringWithFormat:(NSString *)format, ...




nil is equivalent to NULL is equivalent to 0.

nil is the default value of an object pointer. All instance variables start out set to 0.

You can test for nil in an if statement. This is useful to check if a variable has been instantiated or not.



Object Instantiation

There are many different ways to instantiate (to create) an object.

Using class methods:

+ (id)stringWithFormat:(NSString *)format, ...

+ (id)arrayWithCapacity:(NSUInteger)numItems


Using other objects:

- (NSString *)stringByAppendingString:(NSString *)aString

- (NSString *)componentsJoinedByString:(NSString *)separator


From scratch, by allocating and initializing:

  • Allocating: Reserving enough space in memory to hold the object.
  • Initializing: Building the actual object.

- (id)init is the plain object initializer. It is declared in the base class NSObject.

We’ll take a close look at id soon, but for now remember that - (id)init returns an initialized object.

You can override and customize - (id)init in your subclasses.

Objects can have more complicated - (id)init methods. These methods must start with the init prefix and will usually have the format - (id)initWithSomething:(SomeClass *)someInstance.

Objects can also have multiple initializers.

  1. Paul Hegarty. Lecture 3 Slides. iPad and iPhone Application Development. Stanford, Nov 14 2011.

Input and Output




  • Tap, Pinch, Rotation, Swipe, Pan, Long Press
  • Gesture recognizers are built-in for some UI elements, like UIButton and UIScrollView.


  • Can use more than one input point
  • The maximum number of simultaneous touches on iPhone is 5. On iPad, it's 11.



  • Built-in on all iPhones and newer iPods and iPads.
  • Older iPods and iPads require an external microphone attachment.



  • Built-in on all iPhones and newer iPods and iPads.
  • Includes both still image and video capture.
  • Newer devices have a front and back facing camera.
    • Back camera has better resolution than the front camera.
    • Back camera has a flash on iPhone 4 and iPhone 4S.



  • Determined using a combination of information from cellular, Wi-Fi, and GPS networks.
  • Cellular and GPS data is only available on devices with cellular chips (iPhones and iPads with 3G option).
  • GPS accuracy depends on being in a clear line of sight to GPS satellites, i.e. outside with clear skies and no tall buildings around.
  • At best, accuracy will be within 5 meters.

Heading (Direction)

  • Determined using a three-axis gyroscope.


  • Determined using an accelerometer.
  • Commonly used to rotate the visible view so that it's right-side up.


  • Determined using an IR sensor located near the earpiece.
  • Only returns a Boolean flag indicating whether the sensor is close to the user or not.



Screen resolution varies depending on device and model.

Device Model Resolution DPI (ppi) Ratio
iPhone 3GS 320 x 480 163 3:2
4 640 x 960 326 3:2
4S 640 x 960 326 3:2
iPod touch 640 x 960 326 3:2
iPad 2 1024 x 768 132 4:3
New 2048 x 1536 264 4:3

All latest devices have a Retina display. You'll notice that in the table above where some devices have 4 times the resolution of their older counterparts. In a nutshell, Retina means the pixels are so small that the human eye can't detect individual pixels. This makes text a lot clearer and images more vivid.

Selecting between Retina and non-Retina assets is done on-the-fly in iOS applications. In fact, no extra work is required on your part for text and built in UI components. As for external resources such as images, you need to provide two versions of the asset to the application.

  • Both versions should have the same name and extension, but the Retina version should have the @2x suffix added to its name. For example TitleImage.png and TitleImage@2x.png.
  • The Retina version should be double the width and double the height of the regular version. In order not to lose quality, you should work in the highest resolution then downscale your asset by 50% for the regular version.
  • When referencing assets in Xcode and Interface Builder, use the regular versions of the resources.


  • Audio output through the built-in speakers or headphones
  • Vibration can also be triggered, although it should be used sparingly as it is somewhat intrusive and can drain battery life.

  1. Compare iPad Models. Apple Inc., Visited Sep 11 2012.

  2. Compare iPhone Models. Apple Inc., Visited Sep 11 2012.

  3. iPod touch Tech Specs. Apple Inc., Visited Sep 11 2012.

  4. iOS5: Understanding Location Services. Apple Inc., Sep 4 2012.

  5. Matt Gemmell. iPad Multi-Touch. mattgemmell.com, May 9 2010.