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 | ||
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.
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.
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,
NSDateis a direct subclass ofNSObject. Each class can inherit from only one parent, but the inheritance tree can go far back. If you look atNSView, for instance, you will notice that the inheritance tree is a bit longer: NSResponder : NSObject. This means thatNSViewis a subclass ofNSResponder, which in turn is a subclass ofNSObject. That means all methods, delegates, notifications, and constants ofNSResponderandNSObjectare available inNSView. 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
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.







Add a comment



Add a comment