Welcome, new Cocoa or Cocoa Touch programmer.

Here are some things you will need to know.

Cocoa vs. Cocoa Touch

Cocoa is the Mac development framework, principally consisting of Foundation, the Application Kit (a.k.a. AppKit), and Core Data.

Cocoa Touch is the iPhone development framework, principally consisting of Foundation, UIKit, and Core Data. (“iPhone” here means devices running the iPhone OS, including the iPod touch and iPad.)

On Stack Overflow, please don't tag your question cocoa unless it has to do with Cocoa. It's OK to put an iPhone question there as long as it's about something that exists on both platforms. Tagging an iPhone-specific question “cocoa” is inaccurate, and wastes the time of Mac-only programmers like myself.
(You wouldn't want me to tag my Mac-specific questions “cocoa-touch”, would you?)

Critically important things


Objective-C is a programming language. Cocoa and Cocoa Touch are frameworks—collections of Application Programming Interfaces (APIs). You write your code in the Objective-C language, using the Cocoa/Cocoa Touch APIs. All of the NS-prefixed (and, on the iPhone, UI-prefixed) classes, protocols, and categories you'll use are part of the Cocoa and/or Cocoa Touch frameworks, not the Objective-C language.

In Objective-C:

Spelling notes

The IDE is spelled Xcode: Lowercase c, no hyphen.

The object modeling and persistence framework is spelled Core Data: Two words, again with no hyphen. (Not “CoreData” or “Core-Data”). On Stack Overflow, use the core-data tag.

Similarly, Core Foundation, Core Graphics, etc. Apple is not always consistent about this (“CoreGraphics” and “CoreImage” are not uncommon), but outside of pathnames, including the space is never wrong.

On Stack Overflow, tags can't have spaces, so use a hyphen in place of the space: core-foundation, core-data, core-graphics, cocoa-touch. “cocoa touch”, with a space, is two tags, “cocoa” and “touch”.

Core Data

Core Data is:

Core Data is not:

Bindings (Mac only)

It bears repeating: Make model objects. Bindings will kick your ass if you use property-list objects (e.g., dictionaries) as model objects. It looks like less work at first, but it's really not—in Cocoa, model objects pay off because you're working with the framework, not against it.

The Bindings Inspector in Interface Builder distinguishes the Controller Key from the Model Key Path for a reason. Consider the common example of binding a table column in a table view:

Thus, the columns are subordinate to the rows: Each row is a whole model object, broken down into columns, each of which shows part of the object.

In the other direction, if the user edits one of the rows, the cell's value will change, and the table column/table view will set the new object as the model object's new value for the Model Key Path.

This means that it is not possible to use cell editing to replace one object with another in the array, because those objects must be model objects, and the cell can only display and change the value of some property of each object.

There are two solutions to that: (a) Make the model object able to update all of its other properties whenever one of its vital properties is changed (which is fragile, because you will fall behind on the set of properties that need to be updated), or (b) Use a data source, not Bindings.

Bindings is great for certain common cases, but not for everything. There is no shame in using a data source for things that are incompatible with the way Bindings work. Just be sure you aren't doing something deeply wrong, such as not implementing a model layer.

Exceptions vs. errors

Never call an exception an “error”, nor an exception message (printed in the Console) an “error message”. This is wrong. Exceptions and errors are different things for completely opposite purposes.

Errors are things that have gone wrong that the user needs to know about, and possibly to handle.

Exceptions are the opposite: Things that the user should never know happened. Some exceptions (arguably most) should never happen at all, because they indicate that something has gone wrong inside your program. You may use assertions to detect such cases; when an assertion detects such a case (i.e., fails), the assertion failure is an exception.

In Cocoa, the Application Kit provides APIs to let you present errors to the user. It provides no such features for exceptions, because that's not what they're for.

Whenever your app needs to handle a problem, don't reach for exceptions immediately—think about whether the problem is an exception or an error, and use the one that's appropriate.

Windows, plural

On the iPhone, your app normally only has one window, due to both screen size limitations and the current UI model. (It's not yet clear whether this restriction will disappear on the iPad.)

On the Mac, your application has multiple windows. Even if you only create and manage one window, it has others, including the About, Font, Color, Find, and Spelling panels. Even an application that provides no way to access the Font, Color, Find, and Spelling panels (such as a game) will still have an About panel.

So, your application does not have “the window” or “its window”. It has multiple windows. Get used to this; it will matter sooner or later in your app's lifetime.

When practicing with Cocoa, you may want to make a document-based application, at least as a toy app, in order to jump with both feet into the multiple-windows world.

What Cocoa calls “the main window” is the active window: the one that has the active appearance. There's also “the key window”, which is the window that receives key events. These are not always the same window:

Screenshot showing the main window, with active-appearance title bar but dimmed stoplight, and an Inspector panel that's key next to it.

Thus, “the main window” (the active one) may not be what you consider the Main (primary) Window: The About panel, for example, can be main (active) while your Main Window is not. A document-based app has no Main (primary) Window, but as long as it has at least one window, it has a main (active) window.

A window can be key even if it cannot become main, as demonstrated by the Inspector panel in the above screenshot.


Don't use threads.

Your UI, specifically, should always run on the main thread. Cocoa and Cocoa Touch will not work any other way; you will cause problems if you try to force the event loop to happen on another thread. In general, you should consider AppKit and UIKit classes to be main-thread-only.

You don't need to make a thread for every window in your app. Indeed, most of the time, you don't need to make a thread for anything.

You can probably do your actual work on the main thread, as long as you do it asynchronously. Many APIs let you schedule an operation on a run loop (which includes the main event loop in a Cocoa or Cocoa Touch application); the API will get back to you when something happens that you may be interested in. You don't even have to write the loop yourself; it's already written as part of the frameworks (specifically, NS/CFRunLoop).

Threads are dangerous (in the “handle with care” sense) on any platform. Cocoa and Cocoa Touch come with many ways to avoid threads, and so avoid the dangers that come with them.

For cases when you really, really do need to put work onto another thread, use NSOperationQueue or (on the Mac only) Grand Central Dispatch. These APIs will create and manage threads for you; your code will run on threads without swamping the system (usually). Moreover, these APIs encourage you to lay out your code in a cleaner way than you might tend to when using threads directly.

See the Concurrency Programming Guide for more information and good advice.

2010-02-03 http://boredzo.org/cocoa-and-cocoa-touch-intro
Valid XHTML 1.0! Valid CSS!