9781449380373
_the_cocoa_environment.html

Chapter 3. The Cocoa Environment

Programmers who have written Mac OS X or iOS applications using Objective-C are already familiar with Cocoa and should recognize its APIs in the examples in Chapter 1, Introduction, albeit with some odd syntax changes noted in that chapter. Ruby programmers who want an introduction to Cocoa can find it in this chapter. MacRuby lets you mix Ruby and Cocoa APIs seamlessly. But as you start developing Cocoa applications, you will start having to use Cocoa-specific APIs to solve Cocoa-specific challenges.

History

In the early 1980s, two engineers from the company StepStone, named Brad J. Cox and Tom Love, designed a C-based language inspired by SmallTalk-80. Their goal was to implement an object-oriented extension to the C language. The result was called Objective-C.

In 1985, Steve Jobs founded NeXT, a computer platform development company specializing in the higher education and business markets.

In 1988, NeXT licensed Objective-C from StepStone and wrote libraries and a compiler to build NeXTSTEP’s user interface and interface builder. NeXTSTEP, NeXT’s Unix-based operating system was particularly notable because of its focus on object-oriented programming and its many powerful toolkits.

Writing applications for NeXTSTEP was known to be far easier than on many competing systems. The UI was consistent and refined. Tim Berners-Lee, credited as the inventor of the World Wide Web, wrote the very first web browser, called WorldWideWeb, in 1990 on NeXT (Figure 3.1, “Screenshot of WorldWideWeb, the very first web browser”), and even claimed that he could not have done what he did as easily if he had to use other technologies.

 

“I could do in a couple of months what would take more like a year on other platforms, because on the NeXT, a lot of it was done for me already.”

 
 --Tim Berners-Lee, World Wide Web inventor

Figure 3.1. Screenshot of WorldWideWeb, the very first web browser

Screenshot of WorldWideWeb, the very first web browser

WorldWideWeb was not the only ground-breaking application developed on NeXTSTEP. Apple’s Interface Builder, the initial implementations of Doom, Macromedia FreeHand, and Lotus Improv were also built on that platform.

In 1996, NeXT was acquired by Apple, which used parts from NeXTSTEP and from the open source Berkeley Software Distribution systems to build its new operating system: Mac OS X. The new OS included Objective-C as well as NeXT’s developer and interface tools/frameworks, which became the base of the Cocoa API.

Main Frameworks in the Cocoa API

What’s known as the Cocoa API is really a collection of several frameworks. More precisely, it is what is known as an “umbrella framework,” a framework built up from other frameworks.

In this context, when we talk about frameworks, we are referring to application frameworks, which are usually a collection of advanced object-oriented APIs allowing software developers to work in a specific development environment.

Developers writing applications usually spend a lot of time coding the same features over and over: creating and managing a window, creating a menu and menu items, handling undos and redos, and so on.

Apple, and NeXTSTEP before them, saw the need to streamline the application development process. To do that, the two companies decided to provide developers with all the common features required to build Mac OS X applications. OS X developers can rely on these building blocks to focus on the unique values of their applications instead of constantly reinventing the wheel.

Cocoa takes advantage of common object-oriented design patterns and best practices identified and implemented by NeXTSTEP, resulting in a dynamic, mature, consistent, and extensive set of libraries.

The Cocoa API minimum set is an umbrella framework called Cocoa.framework. When loading this framework, you really load three Objective-C frameworks: Foundation, AppKit, and CoreData.

But more than a collection of APIs, the Cocoa framework enforces conventions when it comes to the UI. By using the APIs, you buy into Apple’s view of how the user should see and interact with the device. These conventions also allow for tools such as Xcode to exist and to leverage APIs, while enforcing a consistent user experience.

Note

To use a class from one of these frameworks, you need to make sure to load the framework first. This is also true when using macirb. Each framework can be loaded individually without having to load the entire Cocoa framework. This can be interesting if you are developing an application that doesn’t have a UI, such as a shared library or a script.

Foundation Framework

This is also known as the Foundation Kit. Foundation defines primitive object classes and data types such as strings, arrays, collection classes, dates, XML parser, notifications, IOs, iterators, and run loops. It is the base layer of the Objective-C classes (http://developer.apple.com/mac/library/documentation/cocoa/Reference/Foundation/ObjC_classic/Intro/IntroFoundation.html).

The Foundation framework defines NSObject (the base Object class), as well as subclasses and constants prefixed by “NS” (standing variously for NextStep or NeXT/Sun). Later in this chapter, you will read about the essential classes defined by this framework.

AppKit Framework

This is also known as Application Kit. AppKit is a direct descendant of the original NeXTSTEP Application Kit. It contains all the objects needed to implement graphical, event-driven UI objects, such as windows, panels, buttons, menus, scrollers, and text fields. The framework also handles screen drawing and refresh.

Basically, every time you write a GUI, you will use AppKit.

Note

If you are writing an OS X application that doesn’t require a GUI or a data model based on CoreData, you don’t have to load these Cocoa frameworks.

CoreData Framework

CoreData contains interfaces to manage your application’s data model (http://developer.apple.com/mac/library/referencelibrary/GettingStarted/GettingStartedWithCoreData). Basically, it allows developers to deal easily with objects’ life cycles and graph management. That includes validation, database object change tracking (undo, redo) and propagation, persistence, filtering, fetching, and Cocoa bindings.

In a nutshell, CoreData encapsulates the model in the MVC (model-view-controller) design pattern.

CoreData can be seen as an object-relational mapper (ORM) on steroids. Developers can choose one of the multiple data stores supported: XML, atomic (binary or custom), SQLite, and in-memory.

However, don’t think that CoreData is restricted to database-oriented applications.

Reference Library

Apple’s Reference Library will soon become your best friend. It describes all the Objective-C methods, C functions, and constants made available by the Cocoa API and other various related frameworks. Thanks to MacRuby, they are all accessible to you.

You can access this reference API offline by using Xcode, or online at http://developer.apple.com.

Note

The offline documentation is stored in the /Developer/Documentation/DocSets folder. Using the /Developer/usr/bin/docsetutil utility command line, you can query the documentation. Writing a small application around the docsets can be a great way to get familiar with MacRuby and Cocoa.

After you connect to the Apple Developer Connection website, choose the Mac Dev Center. At this point, if you haven’t created an account, you might want to sign up. Signing up is free and will give you access to the latest version of the Xcode package, as well as some development videos.

In the Development Resources section of the page, you will find some sample code and training videos, but more important, the Mac Reference Library.

The library is maintained and kept up to date by Apple. You will notice that the documents are organized by types, topics, and frameworks. If you find a document that you are interested in, you can download it as a PDF to consult it later offline.

Let’s do a search on NSDate and open the NSDate Class Reference page (Figure 3.2, “NSDate class reference”). API reference documents appear basically the same whether you view them online or via Xcode.

Figure 3.2. NSDate class reference

NSDate class reference

It’s important to understand how the documentation is structured, so you can efficiently find the information you need when you need it.

Central Panel

Inherits from

The inheritance tree of the class we are looking at. In this case, NSDate is a direct subclass of NSObject. Each class can inherit from only one parent, but the inheritance tree can go far back. If you look at NSView, for instance, you will notice that the inheritance tree is a bit longer: NSResponder : NSObject. This means that NSView is a subclass of NSResponder, which in turn is a subclass of NSObject. That means all methods, delegates, notifications, and constants of NSResponder and NSObject are available in NSView. Don’t forget to browse superclasses when learning new classes.

Conforms to

A list of protocols our class conforms to. It’s basically a list of conventions and methods implemented by various other classes.

Framework

The name of the framework defining the class.

Availability

The OS versions supporting the class.

Declared in

The header files defining the class. Not really useful for MacRuby developers, since we don’t need to include any header files.

Companion guides

A list of guides related to the class.

Related sample code

A list of examples using the class in question. Most of these examples are in Objective-C, but since the API usage is the same, you should not have a problem reading them.

Sidebar

The sidebar lists links that cover all the aspects of the class.

In addition to the topics mentioned in the previous section, you will find a new listing. While some sections might be really obvious, some might be a bit more cryptic.

Tasks

Lists class and instance methods by topic. This is particularly useful when you are reading the documentation of a class you don’t know yet. Instead of trying to guess the name of the method, start with this section.

Notifications

The delegate methods triggered on class instances that implement these notification methods.

Mutability

Before looking a bit at some key Cocoa classes, we need to talk about mutability. By definition, an immutable object is an object whose state cannot be modified after being created. In contrast, a mutable object can be modified after creation.

Some Cocoa classes even come in two separate versions, mutable and immutable. Mutable classes descend from their nonmutable counterparts and therefore share the same methods. The main reason for having both classes is that immutable classes are optimized to be more efficient, based on the expectation that their contents are fixed:

framework 'foundation'
mutable_array = []           # => []
mutable_array << 'foo'       # => ["foo"]


immutable_array = NSArray.alloc.initWithArray(['foo', 'bar'])  # => ["foo", "bar"]
immutable_array << 'foo'  # RuntimeError: can't modify frozen/immutable array

Warning

Something else to keep in mind when choosing a Cocoa class: Cocoa doesn’t let you query whether you are dealing with a mutable or an immutable object. That may come as a surprise, but it’s intended. Make sure to always pay attention to documentation for the APIs returning strings, arrays, hashes/dictionaries, and sets (NSArray, NSString, NSDictionary, and NSSet).

Ruby classes are usually mutable, but the state of a Ruby object can be frozen. In other words, in Ruby, you can make a mutable object immutable by freezing it. Cocoa accomplishes this by having two versions of a class, a mutable version and an immutable version:

my_string = "Understanding Ruby"
my_string.freeze
my_string.upcase! # => RuntimeError: can't modify frozen string

array = Array.new   # => []
array << 'foo'      # => ["foo"]

array.freeze
array << 'bar'      # RuntimeError: can't modify frozen/immutable array

Now it’s time to get a quick tour of some of the classes you are going to encounter frequently.

Site last updated on: November 9, 2011 at 10:00:57 AM PST