Categories are an Objective-C syntax for adding features to a class without subclassing it and without even having access to its code (its .m file).

This comes in handy when you want to keep using a specific class (for example NSString) but would like to add an extra feature.

We have seen categories before, when using the AFNetworking framework. UIImageView+AFNetworking is a category on UIImage that allows setting an image using a URL. It does this by adding methods to UIImage such as setImageWithURL: and setImageWithURL:placeholderImage:.

Categories have their own .h and .m files. These are usually named +. These can be easily created through the New File menu in Xcode.

Header Source

Categories can have their own methods and properties, but no instance variables. This means that properties must be implemented and cannot be synthesized.

Header Source

To use a category, we just need to import the header into the class where we need the additional functionality. This will make the extra methods available to use.


User Testing

After building and testing your app yourself, it’s always a good idea to have a select group of users test your app. These users should be representative of your target audience, and they will usually give you good insight on what works well and what doesn’t in your app. This is also a good way to find bugs as these testers will try to use your app in ways you didn’t anticipate.

To add a device for testing, it needs to be registered for Ad Hoc distribution. The tester needs to send their device ID to the developer, who will add it to the developer account. Most Apple Developer Programs allow for a total of 100 test devices, except for the University Program which allows for 200 test devices.

This device ID is then included in an Ad Hoc Provisioning Profile. This profile is a simple file that contains access rights for an app. The provisioning profile can then be added to Xcode and used to build the app, and must be installed on the device at the same time as the app to allow it to run.

The traditional way of doing this is relatively long and demands a lot from the testers:

  1. Find your device identifier (UDID) by connecting it to a computer and launching iTunes.
  2. Email this identifier to the developer.
  3. Wait for the developer to add your device ID to the portal, to compile it in a provisioning profile, and to rebuild the app using this updated provisioning profile.
  4. Receive the app (with extension .ipa) and the profile (with extension .mobileprovision) from the developer.
  5. Drag both files to iTunes.
  6. Sync the apps on your phone.
  7. If everything went well the app should run, otherwise you will need to troubleshoot.

Fortunately for us, a company called TestFlight has developed a process for distributing apps to testers that is easy and painless. A user simply needs to visit the website on their device and follow the simple steps to create an account and register their device. Once that’s done, a developer can add them to a team and prepare an app for testing without requiring more info from the tester. Once the app is ready, the developer simply uploads it to the TestFlight site where it becomes available to all testers for download. There is no need to manage files or to connect the device to a computer.

Another great feature of TestFlight is that it automatically logs errors and crashes for the app, so that if something goes wrong, the developer can investigate without having to ask the tester for details they probably will not be able to provide.


Once your app is ready for the general public, it is time to package a release build for it. The most common distribution platform is the App Store, but depending on the Developer Program you are registered in, you might also be able to build apps for In House distribution.

In House distribution essentially means bypassing the App Store and is typically used for distributing apps on a group of devices within an organization. The process is very similar to Ad Hoc distribution. You create a specific In House Provisioning Profile which you use to build the app. The main difference is that you don’t need to populate a list of device IDs as the app can run on any device. You can then install the app on the actual devices using iTunes or TestFlight.

App Store distribution is a little more complicated. Once again, you need to create a specific App Store Provisioning Profile and build the app against it. This app is then submitted to Apple using the iTunes Connect tool. You will need to fill out information about the app (description, category, icons) which will be used in the App Store. Your submission will then have to be approved by someone at Apple, and that can take anywhere from a couple of days to a few weeks depending on how busy they are.

Once your app is approved, it will go up in the store and stay available as long as you keep paying your $99 yearly developer fees.

If your app gets rejected, you will usually get a specific reason as to why it was rejected, and you will be able to resubmit once you fix whatever it is that Apple did not like. Unfortunately, your app will go back at the end of the submission queue, and it could take a few days until it is reviewed again.


Core Data

There are many different ways to save and load data for your app. We’ve already been using NSUserDefaults for storing preferences and small amounts of data. For larger data sets, you can use XML files or an SQLite database. This data can then be read and written directly, but that tends to be more complicated than you’d expect.

That’s where Core Data comes in. It is a framework that allows you to manipulate your data directly in Objective-C. A lot of the setup and connection work is already taken care of, and you create your data models and relationships using a graphical interface. Behind the scenes, the actual data files can be XML, SQLite or binary, and your application will still access it in the same way.

To use Core Data in your project, you need to check the corresponding box on the New Project window. Note that this option does not appear for all project types, so make sure to pick a Master-Detail Application.

Core Data Classes

The managed object model is like the database schema. This class that contains the definitions for each of the objects that you are storing in the database. You will hardly ever create or edit this file in code, but do so visually using the .xcdatamodeld file in the project.

The persistent store coordinator is like the database connection. You use this object to set the name, type, and location of your database. Any save operation also goes through this single connection which, as its name implies, keeps all the data coordinated.

The managed object context is like the “scratch pad” for objects. Whenever you need to get, delete, or insert objects in the persistent store, you will call methods on the managed object context.

The managed object is a generic class that is at the base of any Core Data models. Think of it as NSObject for Core Data.

You will always have a single instance of the NSManagedObjectModel, NSPersistentStoreCoordinator, and NSManagedObjectContext. You will usually have many instances of many different NSManagedObject subclasses.

If we look at the App Delegate implementation in the project we just created, we can see how each of these objects is created.

First, the model is loaded from the visual file.

Then, the model is used to build a connection to the persistent store. You’ll notice that by default, this is an SQLite database stored in the application’s documents directory.

And finally, a managed context is created and linked to the persistent store coordinator.

Defining the Model

The model for the data is defined in the .xcdatamodeld file. Objects are called entities here, and they hold attributes with a name and a type. You can also create relationships linking entities together.

You build a new entity by clicking the Add Entity button at the bottom. You can then assign a set of attributes to this entity.

The entity can also have relationships to others. You can customize the type of relationship in the Data Model Inspector on the right.

In our example, a Session can have any number of Events (including none), and an Event can only be linked to one Session. Furthermore, if you delete a Session, it will automatically delete all linked Events, because we set the Delete Rule to Cascade.

Reading and Writing

We want to create a new Session every time the Master view is shown on screen. We will first check if any Sessions already exist in the store.

The first step is to build an NSFetchRequest for the requested entity.

We will then execute the request on the managed object context and retrieve all of the results in an NSArray. We can then check whether or not any Sessions exist by looking at the number of elements in the array.

If no previous Session exists, we’ll create a new one with number set to 1. Note that we use the setValue:forKey: method to set the entity attributes.

Once our new Session is created, we need to save the managed object context to the store.

If a previous Session already exists, we’ll create a new one with number set to the incremented value of whatever the last number was.

First we’ll need to sort the fetched results using an NSSortDescriptor.

We can then read the highest Session number, and use that value to build our new Session. Note that we use the valueForKey: method to read entity attributes.

We can clean up our implementation by removing duplicate code.


If you try to add a new entry to the table, the app will crash because the Event entity now requires a relationship to a Session.

First, we will add an attribute to store the current Session to our MasterViewController class.

We can then add the Session value to any newly created Event.

If we print out our fetch results, we’ll see that Events are automatically added to the Session‘s events array. This is because and Event.session are set as inverse relationships.

Strongly-Typed Models

So far, we’ve used the base NSManagedObject class to access our data, and the setValue:forKey: and valueForKey: methods for setting and getting attributes and relationships. Although this can work fine, it can lead to errors and typos as we are not getting any help from the compiler to use the correct names and types.

A better way of doing this is to create a model class for each entity.

  1. Open the .xcdatamodeld file.
  2. Select an entity.
  3. Go to the File / New / File… menu and select the NSManagedObject subclass option.

  1. This will generate and add a header and implementation file to the project.
  2. Repeat with the remaining entities.

You can now use these subclasses instead of the base NSManagedObject.

  1. Core Data Programming Guide. Apple, Sep 19 2012.
  2. Core Data on iOS 5 Tutorial. Ray Wenderlich, Apr 13 2010.


Many of the frameworks listed below are written in the C++ language. C++ is an object-oriented superset of C, much like Objective-C is. It is one of the most popular programming languages and can be used directly in your iOS programs.

  • Source code header files always use the .h extension.
  • Source code implementation files written in pure C and Objective-C use the .m extension.
  • Source code implementation files written in C++ use the .cpp extension.
  • Source code implementation files written in in both Objective-C and C++ use the .mm extension.

C++ is a very powerful language that is less abstracted than Objective-C. This means that it will generally be more complicated but offer better performance. One of the main differences you might notice is that you’ll have to manually manage your memory (allocations and deallocations). However, most of the frameworks listed below include some type of reference counting.


openFrameworks is an open source C++ toolkit for creative coding. Its design is heavily influenced by Processing, which should make many of the functions familiar to you. openFrameworks was originally created for high-performance graphics and video processing, but can be used for a variety of applications.

A few years ago, openFrameworks was ported to iOS, allowing desktop applications to run on mobile devices without changing a single line of code. Many successful iOS apps are built with openFrameworks, such as SpellTower.

One of the strengths of openFrameworks is its large user base and their dedication to open source software. You can find a long list of contributed addons which can help you perform a variety of tasks. If you’re stuck on a problem, you can browse through the forum or post a new question, and it will most probably be answered within the hour.

You can download the iOS version of openFrameworks here and follow the setup guide to get started. This solution will create an app that is “openFrameworks driven”, meaning that most of your code (if not all) will be part of the openFrameworks project. Alternatively, you can use the ofxiOS addon, which treats openFrameworks projects similarly to other views, and keeps your app “Objective-C driven”.


Cinder is another creative coding library for C++. The main difference with openFrameworks is that it uses more specific system libraries instead of opting for cross-platform open-source solutions. This will usually result in better performance but is more complex to use and code. Cinder also makes heavy use of C++ namespaces, which can be confusing and hard to read. Cinder is aimed and experienced developers, so it’s harder to get into if you don’t know what you are doing.

There are a few Cinder apps in the App Store, notably DMesh and Planetary.

The Mac version of Cinder can be downloaded here and includes compilation targets for iOS.


pocode is yet another C++ library for interactive media. Whereas openFrameworks and Cinder are all about high performance graphics, pocode’s strength lies in interface design. It borrows a page from Flash where every object has spatial properties (position, rotation, scale), built-in event handlers, and a cascading parent-child relationship.

pocode for Mac can be downloaded here and includes iOS templates and compilation targets.


C4iOS is the newcomer to the game, having only been released a few months ago. It is also a creative coding toolkit, but unlike the frameworks listed above, C4iOS is written in Objective-C. Instead of having to switch in and out of a special C++ view, you can simply use C4iOS objects directly in your code. As the name implies, C4iOS is also iOS specific and works seamlessly with multitouch interactions and gestures.

Although C4iOS still does not have a very large user base, it has very clear and complete documentation, including examples and tutorials. It’s also Canadian, so +1 for that :)

C4iOS can be downloaded from here.


Cocos2D is an open source game engine that has been ported to many different languages and platforms, including Objective-C for iOS. It only supports 2D, meaning that it’s a great toolkit to build a puzzler or platformer, but not ideal for a shooter.

Cocos2D simplifies the process of creating scenes in apps (for example a menu scene, a game scene, a high score scene, etc.) It uses OpenGL ES for rendering and can easily incorporate one of two robust and popular physics engines: Box2D and Chipmunk.

Cocos2D has been used by many games and apps in the App Store, including FarmVille, Trainyard, and Björk’s Biophilia.

Cocos2D can be downloaded from here.


Unity is a multi-platform game engine with a port for iOS. It is the industry standard for developing high performance, complex games, and its $1500 price reflects that. You can however download a limited version free-of-charge, but will still need the $400 iOS plugin.

Unity projects are built in C#. It can be used to build 2D and 3D environments and includes a multitude of plugins for animation, modeling, physics, etc.

Unity is used for many games in the App Store, such as Triple Town and Shadowgun.


The Open Graphics Library (OpenGL) is a framework for rendering 2D and 3D graphics. OpenGL usually interacts directly with the GPU, achieving hardware-accelerated rendering. OpenGL is a cross-platform, multi-language API and it is widely used in visualization software and video games.

OpenGL ES is the version of the library that runs on embedded devices such as the iPhone and iPad. It is a subset of desktop implementations of OpenGL. There are two versions of OpenGL ES available for use on iOS. Version 1.1 uses a fixed pipeline, meaning that you use a set of built-in functions to build your scene. Version 2.0 uses a programmable pipeline, meaning that there are no built-in functions and everything must be built from scratch. As you’ve probably guessed, 2.0 is a lot more complicated but allows for more control than 1.1. For this lesson, we’ll be using version 1.1 as we’re just getting our hands dirty with OpenGL.

The OpenGL API for iOS is written in pure C, much like the Core Graphics framework, and integrates seamlessly with Objective-C classes. You need to link against three additional frameworks to use OpenGL code in your apps: Quartz Core, OpenGL ES, and GLKit.

GL View

GLKView is a UIView subclass used to render OpenGL graphics.

The GLKView needs to be attached to an EAGLContext. This is a drawing context, which manages all of the data iOS needs to draw with OpenGL.

The GLKView must also be connected to a GLKViewDelegate, which will be polled periodically to draw content in the view. This is done by implementig the glkView:drawInRect: method.

We can try pulsing the red background by using a couple of variables to set the color.

You’ll notice that this does not work as expected, and that is because glkView:drawInRect: is not called regularly. Similarly to drawInRect:, this method is only called when the view is first shown, when it is resized, etc.

When using OpenGL, you will often need to redraw the view at every frame. We need to replace the default redraw behaviour by another that redraws in sync with the screen refresh rate. This can be achieved using a CADisplayLink timer.

GL View Controller

We just saw how to build and render to a GL view from scratch. GLKit offers a much easier solution for doing this using a GLKViewController. This is a UIViewController subclass that also implements an OpenGL ES rendering loop. The GLKViewController will create the GLKView and set itself as its delegate automatically, but you still need to set the EAGLContext manually.

Header Source

At this point, it’s a good idea to cleanly initialize and destroy the context.

GLKViewController also provides us with an update method, which is called every frame like the draw method, but intended for app logic.

GLKViewController allows us to set the desired frame rate using the preferredFramesPerSecond property. Note that the actual frame rate may be lower than this, depending on how long it takes to render a frame. The actual frame rate can be read using the framesPerSecond property.

Drawing Shapes

Rendering geometry in OpenGL is done using vertices (points). Vertices can have multiple properties such as position, colour, texture coordinates, etc. These vertices can be passed to the buffer using many different methods. We will use one of the simplest called vertex arrays.

Note that the origin (0, 0) is set to the center of the view by default.

OpenGL ES can only render triangles, so you will often need to combine multiple triangles to build the desired shape.

As we are only working in 2D, we can get rid of the z-coordinate.

We can set the shape color using glColor4f(). This will change the color of anything that is drawn until the next call to glColor4f().

We can also set the color on a vertex-by-vertex basis by passing a color array along with the vertex array.

We can optimize our data by removing duplicate points. We can then use an index array to indicate the order in which the vertices should be drawn.

  1. Beginning OpenGL ES 2.0 with GLKit Part 1. Ray Wenderlick, Oct 19 2011.
  2. OpenGL ES Programming Guide for iOS. Apple, Feb 24 2011.

App Design Guidelines

Before diving into code, you need to take the time to properly design your app, both from an interface and experience point of view. It is important to take the time to define an app’s feature set and intended audience to help guide the design process. This must be done while keeping in mind the features and limitations of the platform this app will run on. Tailoring the experience to the function, to the user, and to the platform are all necessary to the development of a successful app.

  1. Determine what the app’s main purpose is.
  2. List all the features you think are important for this purpose.
  3. Determine who your users are.
  4. Filter the feature list for your audience.
  5. Filter the feature list for the target platform.

Platform Characteristics

The display is at the heart of the user experience as it is both the main input and output interface. The content is viewed on screen and the experience is driven by touching that same screen.

Users must be able to “grab” a control without seeing it. All controls should therefore be large enough and spaced apart enough so that there is no confusion when they are being selected. A good rule of thumb is to have controls of at least 44 x 44 points in size.

The device being handheld, it is often rotated in different orientations. This can happen for a variety of reasons, from the user being tired to feeling that some tasks are more natural in specific orientations. This is something that must be taken into account and accommodated in the app design if it makes sense.

Finally, it is important to remember that apps respond to gestures, as opposed to mouse clicks and keyboard typing on desktop devices. Furthermore, a gestural language has been established over the last few years because it has been adopted by many apps, and should be considered when designing interactions. For example, dragging to scroll or pan, and pinching to zoom in and out.

Human Interface Principles

A great user interface does not focus on the device capabilities but on the way users think and work. It must be inviting, simple, and intuitive.

Aesthetic Integrity – How well does the appearance of the app integrate with its function? For example, a game should be immersive and take over the entire screen, while a to-do list should be more subtle and sober.

Consistency – This includes both consistency with other apps and within the app itself. Does the app take advantage of established standards users are comfortable with? Does the app maintain its visual identity throughout the experience? Do UI elements mean the same thing and are used the same way all the time?

Direct Manipulation – The multi-touch screen allows users to directly manipulate elements instead of going through a separate interface. For example, instead of having buttons for zooming in and out of an image, use a pinch gesture.

Feedback – Users expect immediate feedback when interacting with an interface. If an operation takes a long time, like a network request for example, let them know that the system is “thinking”. If an operation takes longer than expected, offer a status update reassuring them that everything is under control.

Metaphors – References to real life objects allow users to quickly understand how to use an interface. For example, a switch can be flicked to toggle a setting, or a rotary dial can be turned to fine tune a value.

User Control – The user should always initiate any action and feel in control while using the app. Users also expect to be able to undo or cancel an action that is underway.

User Experience Guidelines

Focus on the primary task – If a feature does not relate to the main purpose of the app, it is unnecessary. This also works on a feature basis. You should analyze what information is needed in each screen, and get rid of anything extra (either including it in a different context or removing it altogether).

Emphasize the content users care about – Decrease the weight of the UI by minimizing the number of controls and their prominence on screen. For example, you can fade away navigation controls in a slideshow if the user has not interacted with them for a few seconds.

Think top down – The top of the screen is most visible to users as they tend to hold the device in their hand, interacting with the screen using their thumb. The most important and frequently used information should be placed at the top.

Make usage easy and logical – Navigation through the app should be predictable. Users should immediately understand how to use the app and where to find information they are looking for. For example, clicking on a person’s name in the address book reveals their contact information.

Use user-centric language – You want to avoid technical terms and keep terminology simple yet accurate. For example, “load a webpage” instead of “perform an HTTP request”.

Keep file-handling in the background – Users do not expect to have to deal with files and folders on a handheld device. Information about file paths, saving, loading are usually irrelevant to the experience and should happen silently.

Start instantly – Users tend to interact with apps for only a few minutes at a time. Avoid splash screens, only display about screens on user request, and delay login screens as much as possible.

Always be prepared to stop – Save data reasonably often and save the app state when it moves to the background to allow the user to continue where they left off.

Make it pretty – Use beautiful graphics and subtle animations to make your app attractive and enjoyable to use.


It is often useful to start thinking about an app outside of Xcode and even completely offscreen. Although a napkin and a pen are good enough to sketch out an initial idea, some tools can come in handy when moving forward into more concrete interface and experience design.

Pen and Paper

iPhone Application Sketch Template (Oliver Waters) – Printable iPhone template with grid squares at every 10 pixels, and tick marks indicating the position of the status bar, navigation bar, and tab bar.

App Sketchbook (Square Position, LLC) – Booklet with iPhone or iPad stencils for sketching mockups, with a notes section at the bottom of the page.

Stencil Kit (UI Stencils) – Stencils for commonly used iPhone and iPad controls and icons. A sketchpad and PDFs at the same scale are also available.


iPhone Mockup (Lukas Mathis) – Online stylized design tool including standard component library. Designs can be collaborated on by sharing the URL.

MockFlow – Online wireframing tool with a large library of user-generated content.

OmniGraffle (OmniGroup) – Diagramming application that can be used for creating wireframes and flowcharts. Many free iPhone and iPad stencils can be downloaded from Graffletopia (and various other places on the web) for interface design.


iOS 6 GUI PSD (iPhone 5) (Geoff Teehan) – Photoshop document containing a complete and well-organized collection of standard UI elements for iOS.

iOS Photoshop Actions & Workflows (Bjango) – Photoshop actions for performing common iOS design tasks.

DevRocket (Ui Parade) – Photoshop plugin for performing common iOS design tasks.


Cocoa Controls – Collection of user submitted interface elements for iOS apps.

  1. iOS Human Interface Guidelines. Apple, Sep 19 2012.

Settings Bundle

As we’ve seen previously, NSUserDefaults is used to store preference data in iOS apps. There are then two options for displaying these preferences: directly inside the app and as a section in the Settings app.

Where you display preferences is up to you, and how you expect your users to interact with preferences. Usually, you’d want preferences that are accessed frequently inside the app. When displaying preferences inside the app, it’s up to you to decide how and where to display them.

However, a specific format must be followed to display the preferences in the Settings app. This is done using a Settings bundle, a collection of files describing the structure and presentation style of the preferences.

You can create a Settings bundle in Xcode using the New File menu.


This will generate two files in the bundle. The one holding all the configuration options is Root.plist. .plist stands for preference list, and it’s just an XML file.

Preferences items are set by adding entries to the list. Each entry has an identifier and a type, and a few extra options depending on the type. The file generated by Xcode is prepopulated with 4 entries: a Group, a Text Field, a Toggle Switch, and a Slider. You can see these by running the app on a device or the simulator, and then opening the Settings app.

The identifier is used to access the value of the preference in the app.

To add a preference, you simply add an entry to this list. There are many types of preference items.

  1. Group creates a new group of items. All items below this one will be part of the group, until the next Group item.
    • Title
  1. Text Field displays an editable text field, with an optional title.
    • Title – The text field name (optional).
    • Autocapitalization Style – Options to capitalize words, sentences, or all characters.
    • Autocorrection Style – Whether or not to autocorrect the input text.
    • Keyboard Type – The type of keyboard to display when editing (Email Address, Number Pad, etc.)
    • Text Field Is Secure – Replaces typed characters by (useful for passwords).
    • Default Value
  2. Toggle Switch displays an ON/OFF button.
    • Title
    • Default ValueYES or NO.
  3. Slider displays a slider, with customizable range.
    • Minimum Value – A number.
    • Maximum Value – A number.
    • Default Value – A number.
  4. Multi Value pushes the view to display a set of options to choose from.
    • Title
    • Titles and Values – Arrays holding the titles and values for each option. Both arrays should hold the same number of elements in matching order.
    • Default Value
  1. Title displays a read-only label.
    • Title
    • Default Value
  1. Child Pane displays a link to another .plist file, which can be used to display more options.
    • Title
    • Filename – The name of the linked .plist file.

Constants and Statics


A constant is an identifier whose value cannot be changed. It is said to be read-only. Think of it as a literal that can be referenced by name. Constants are useful when you need to reuse a literal value, for example when setting a margin for multiple UIView objects. If this margin ever needs to change, you would only need to do it once where the constant is defined instead of throughout the code.

A constant is defined using the const keyword.

Constants must be declared and defined on the same line. If you try to do this in more than one step, the compiler will throw an error, thinking that you’re trying to edit the constant.

It’s important to be able to recognize constants in your code, so you should use a different format than variables for naming them. There are many different conventions used for naming constants. One is to capitalize the name and use underscores for spacing.

Another is to prefix the name with the letter k.

Constants are widely used to store names for keys and identifiers. We can edit our notifications app from last class to do just that.

Read-only Properties

Sometimes you’ll want to make properties available to outside classes only for viewing (reading) and not for editing (writing). This can be achieved by adding the readonly modifier when declaring a property. What this does behind the scenes is only create a getter and not a setter for the property variable.


A macro is a find-and-replace rule applied to source code before it is compiled. Macros are declared using the #define keyword.

Macros look very similar to constants, and are often used for similar purposes. However, the way they are integrated into source code is very different. Constants are handled similarly to variables by the compiler. They are stored in a table in memory, and their value is read whenever their name is encountered during compilation. Macros are interpreted in the pre-compilation phase. Much like a find-and-replace operation, a script goes through the entire code and replaces any occurrences of the macro name with its value. Macros have the advantage of running faster, since their value is immediately available. Constants on the other hand, are more useful for debugging, as they can be referenced when an application runs.

Another main difference is that constants are typed, whereas macros are not.

Macro errors can also be hard to debug as the compiler will not always provide you with a relevant message. Consider the following two seemingly correct macro definitions.


One of the greatest advantages of macros is that you can use them to write small scripts. These scripts can be used like functions, as they will get inserted wherever the macro is used.

You can even pass arguments to macros if needed.

Static Attributes

A static attribute is owned by the class itself, as opposed to by an instance of that class. Its lifetime spans the entire time that the app is running, as it is not associated with any particular instance of the class.

We’ve already seen static methods before, they are the methods whose definition begins with a +. In Objective-C, these are called class methods. One of the most commonly used ones is NSString‘s stringWithFormat:.

Variables can also be static and these are used locally inside a class implementation. They are defined using the static keyword.

You can initialize static variables in the initialize class method. This method is called on every class in an app before it is used.

A static variable can be used by any instance of the class it belongs to.

If you ever want to use a static variable outside of the class its defined in, you need to create a static getter for it.

Header Source


The singleton design pattern is used when you want to restrict the instantiation of a class to a single object. Note that this is not the same as having a static class; The class does get instantiated, but only once. This is particularly useful when you need some type of coordination within the entire app. An example of this would be a data manager singleton, which ensures that the entire app is populated with the same set of data, and that any change to this data is reflected all around.

When creating a singleton, you need to insert checks to ensure that only one instance of the class is ever created. This can be done by using a static variable for the singleton, and setting it up in the initialize class method.

Header Source

As nothing prevents the rest of the program to call initialize directly, we need to add a check to make sure our singleton is only instantiated once.

We can simplify this even more, by initializing our singleton directly in the getter.

This will work fine in most situations. However, it does not take a special case into consideration. If two threads in your app try to access the singleton at the same time, sharedInstance might be called a second time before it completes its first run, and might create two instances of the singleton. Although this is unlikely, it might happen, and a safety against this condition must be created. This is also the type of bug that is nearly impossible to track down, so it’s better to be safe than sorry.

Using a @synchronized block will ensure that whatever code is inside of it will never execute more than once concurrently.

  1. Constant (programming). Wikipedia, Sep 24 2012.

  2. Macro (computer science). Wikipedia, Oct 24 2012.

  3. Singleton pattern. Wikipedia, Oct 23 2012.


Notifications are messages that are sent between objects. Unlike delegates, which are specifically linked to the object sending the message, notifications are broadcast and intercepted without any link between the sender and receiver. In fact, there can even be multiple receivers listening for a notification. Think of it like a radio station, which broadcasts a program whether it has listeners or not, and like radio receivers which can tune in to receive that program.

The NSNotification object is used to build a message. A message contains three properties:

  • The name is the message identifier.
  • The object is the sender of the message.
  • The userInfo is an NSDictionary containing information about the message.

You can create an NSNotification using the notificationWithName:object:userInfo: class method. Chances are, however, that you’ll never create a notification directly, but do so through the notification center.

Notification Center

The NSNotificationCenter provides a mechanism for broadcasting information within a program. This would be the radio station in our analogy.

Each app has a default notification center you can use. You typically will never need to create your own. To access this notification center, you use the defaultCenter class method.

Listening for Notifications

Any object can register with a notification center to receive NSNotifications using the addObserver:selector:name:object: method. The object parameter is used to set a specific notification sender, but you can also pass nil to register for all notifications identified by the name parameter.

An object can also register for a notification using a block handler. This is done with the addObserverForName:object:queue:usingBlock: method. The queue parameter is used in multithreading environments, but since we haven’t looked at that yet, you can just pass nil to use the main thread.

You use removeObserver:name:object: to stop listening for a notification.

You can also call removeObserver: to stop listening for all notifications.

Posting Notifications

Posting notifications is also done through the NSNotificationCenter, using either the postNotificationName:object: or postNotificationName:object:userInfo: methods, depending on whether or not you need to pass info along.

Displaying Web Content

UIWebView is used to display web content. UIWebView is simply an extension of UIView with URL loading and displaying capabilities, so it can be used wherever you would use a UIView. UIWebView is built using the WebKit framework, which is the same set of libraries used in Safari, making it surprisingly fast.

You can add a web view directly in the Storyboard. You can also set whether or not the web view scales pages to fit on the device screen. This can also be done in code by setting the scalesPagesToFit property.

Web pages are loaded using NSURLRequest.

Header Source

UIWebView has some built-in navigation methods you can call to control page display:

  • goBack loads the previous page in the stack. canGoBack determines if we are at the bottom of the stack.
  • goForward loads the next page in the stack. canGoForward determines if we are at the top of the stack.
  • reload reloads the current page.
  • stopLoading stops loading whatever content it’s loading.

These actions can be linked directly in the Storyboard.

The web view delegate can receive information on when page loads starts and ends. It must conform to the UIWebViewDelegate protocol. We can use this information to update button states in our user interface.

Header Source

You can also implement webView:didFailLoadWithError: to handle any errors.

You can add a UIActivityIndicatorView to give more feedback to the user.

Header Source