93
Mac App Programming Guide

Mos x App Programming Guide

Embed Size (px)

Citation preview

Page 1: Mos x App Programming Guide

Mac App ProgrammingGuide

Page 2: Mos x App Programming Guide

Contents

About Mac OS X App Design 7At a Glance 7

Cocoa Helps You Create Great Apps for Mac OS X 7Common Behaviors Make Apps Complete 8Get It Right: Meet System and App Store Requirements 8Finish Your App with Performance Tuning 8

How to Use This Document 9See Also 9

The Mac Application Environment 10An Environment Designed for Ease of Use 10A Sophisticated Graphics Environment 11Low-Level Details of the Runtime Environment 12

Based on UNIX 12Concurrency and Threading 13The File System 13Security 18

The Core App Design 21Fundamental Design Patterns 21The App Style Determines the Core Architecture 23

The Core Objects for All Cocoa Apps 26Additional Core Objects for Multiwindow Apps 29Library-Style Apps Should Not Use NSDocument 30

Document-Based Apps Are Based on an NSDocument Subclass 30Documents in Mac OS X 31The Document Architecture Provides Many Capabilities for Free 31

The App Life Cycle 32The main Function is the App Entry Point 33The App’s Main Event Loop Drives Interactions 34Automatic and Sudden Termination of Apps Improve the User Experience 35

Support the Key Runtime Behaviors in Your Apps 36Automatic Termination 36Sudden Termination 37

2012-01-09 | © 2012 Apple Inc. All Rights Reserved.

2

Page 3: Mos x App Programming Guide

User Interface Preservation 38Apps Are Built Using Many Different Pieces 43

The User Interface 43Event Handling 44Graphics, Drawing, and Printing 45Text Handling 46

Implementing the Application Menu Bar 47Xcode Templates Provide the Menu Bar 47Connect Menu Items to Your Code or Your First Responder 47

iCloud Storage 49Design Considerations for iCloud Apps 50Configuring Your App’s iCloud Entitlements 52Using iCloud Document Storage 54

Determining if iCloud Document Storage is Available 55Incorporating File Presenters into Your Workflow 55Manipulating Files and Directories in iCloud 56Choosing a Strategy to Respond to Version Conflicts 57Incorporating Search into Your Infrastructure 58Determining the Transfer Status of a File or Directory 59Working With Files That Are Not Yet Downloaded 60Updating Your User Interface for iCloud 61Using iCloud in Conjunction with Core Data 62

Using iCloud Key-Value Data Storage 64Being a Responsible iCloud App 64

Implementing the Full-Screen Experience 66Full-Screen API in NSApplication 66Full-Screen API in NSWindow 67Full-Screen API in NSWindowDelegate Protocol 67

Supporting Common App Behaviors 70You Can Prevent the Automatic Relaunch of Your App 70Making Your App Accessible Enables Many Users 70Provide User Preferences for Customization 73Integrate Your App With Spotlight Search 74Use Services to Increase Your App’s Usefulness 75Make Use of Resolution Independence 75Prepare for Fast User Switching 76Take Advantage of the Dock 77

2012-01-09 | © 2012 Apple Inc. All Rights Reserved.

3

Contents

Page 4: Mos x App Programming Guide

Build-Time Configuration Details 78Configuring Your Xcode Project 78The Information Property List File 79The Mac OS X Application Bundle 81Internationalizing Your App 84

Tuning for Performance and Responsiveness 86Speed Up Your App’s Launch Time 86

Delay Initialization Code 86Simplify Your Main Nib File 87Minimize Global Variables 87Minimize File Access at Launch Time 88

Don’t Block the Main Thread 88Decrease Your App’s Code Size 88

Compiler-Level Optimizations 89Use Core Data for Large Data Sets 90Eliminate Memory Leaks 90Dead Strip Your Code 90Strip Symbol Information 91

Document Revision History 92

2012-01-09 | © 2012 Apple Inc. All Rights Reserved.

4

Contents

Page 5: Mos x App Programming Guide

Figures, Tables, and Listings

The Mac Application Environment 10Table 1-1 Key directories for Mac OS X apps 14Table 1-2 Attributes for the Mac OS X file system 17Listing 1-1 Getting the path to the Application Support directory 16

The Core App Design 21Figure 2-1 The Calculator single-window utility app 24Figure 2-2 The iPhoto single-window app 25Figure 2-3 TextEdit document window 26Figure 2-4 Key objects in a single-window app 27Figure 2-5 Key objects in a multiwindow document app 29Figure 2-6 Document file, object, and data model 31Figure 2-7 The main event loop 34Figure 2-8 Responder objects targeted by Cocoa for preservation 39Figure 2-9 Windows and menus in an app 43Figure 2-10 Processing events in the main run loop 44Table 2-1 Fundamental design patterns used by Mac OS X apps 21Table 2-2 The core objects used by all Cocoa apps 27Table 2-3 Additional objects used by multiwindow document apps 30Listing 2-1 The main function of a Mac OS X app 33Listing 2-2 Returning the main window for a single-window app 42

iCloud Storage 49Figure 3-1 Pushing document changes to iCloud 54Table 3-1 Differences between document and key-value storage 51

Implementing the Full-Screen Experience 66Table 4-1 Window delegate methods supporting full-screen mode 68

Supporting Common App Behaviors 70Figure 5-1 Universal Access system preference dialog 72Figure 5-2 Spotlight extracting metadata 74

Build-Time Configuration Details 78

2012-01-09 | © 2012 Apple Inc. All Rights Reserved.

5

Page 6: Mos x App Programming Guide

Figure 6-1 The information property list editor 80Figure 6-2 The Language preference view 85Table 6-1 A typical application bundle 81

Tuning for Performance and Responsiveness 86Table 7-1 Compiler optimization options 89

2012-01-09 | © 2012 Apple Inc. All Rights Reserved.

6

Figures, Tables, and Listings

Page 7: Mos x App Programming Guide

This document is the starting point for learning how to create Mac OS X apps. It contains fundamentalinformation about the Mac OS X environment and how your apps interact with that environment. It alsocontains important information about the architecture of Mac OS X apps and tips for designing key parts ofyour app.

At a GlanceCocoa is the application environment that unlocks the full power of Mac OS X. Cocoa provides APIs, libraries,and runtimes that help you create fast, exciting apps that automatically inherit the beautiful look and feel ofMac OS X, as well as standard behaviors users expect.

Cocoa Helps You Create Great Apps for Mac OS XYou write apps for Mac OS X using Cocoa, which provides a significant amount of infrastructure for yourprogram. Fundamental design patterns are used throughout Cocoa to enable your app to interface seamlesslywith subsystem frameworks, and core application objects provide key behaviors to support simplicity andextensibility in app architecture. Key parts of the Cocoa environment are designed particularly to support easeof use, one of the most important aspects of successful Mac OS X apps. Many apps should adopt iCloud toprovide a more coherent user experience by eliminating the need to synchronize data explicitly betweendevices.

2012-01-09 | © 2012 Apple Inc. All Rights Reserved.

7

About Mac OS X App Design

Page 8: Mos x App Programming Guide

Relevant Chapters “The Mac App Environment” (page 10), “The Core App Design” (page 21), and“iCloud Storage” (page 49)

Common Behaviors Make Apps CompleteDuring the design phase of creating your app, you need to think about how to implement certain featuresthat users expect in well-formed Mac OS X apps. Integrating these features into your app architecture can havean impact on the user experience: accessibility, preferences, Spotlight, services, resolution independence, fastuser switching, and the Dock. Enabling your app to assume full-screen mode, taking over the entire screen,provides users with a more immersive, cinematic experience and enables them to concentrate fully on theircontent without distractions.

Relevant Chapters “Supporting Common App Behaviors” (page 70) and “Implementing theFull-Screen Experience” (page 66)

Get It Right: Meet System and App Store RequirementsConfiguring your app properly is an important part of the development process. Mac OS X apps use a structureddirectory called a bundle to manage their code and resource files. And although most of the files are customand exist to support your app, some are required by the system or the App Store and must be configuredproperly. The application bundle also contains the resources you need to provide to internationalize your appto support multiple languages.

Relevant Chapter “Build-Time Configuration Details” (page 78)

Finish Your App with Performance TuningAs you develop your app and your project code stabilizes, you can begin performance tuning. Of course, youwant your app to launch and respond to the user’s commands as quickly as possible. A responsive app fitseasily into the user’s workflow and gives an impression of being well crafted. You can improve the performanceof your app by speeding up launch time and decreasing your app’s code footprint.

About Mac OS X App DesignAt a Glance

2012-01-09 | © 2012 Apple Inc. All Rights Reserved.

8

Page 9: Mos x App Programming Guide

Relevant Chapter “Tuning for Performance and Responsiveness” (page 86)

How to Use This DocumentThis guide introduces you to the most important technologies that go into writing an app. In this guide youwill see the whole landscape of what's needed to write one. That is, this guide shows you all the "pieces" youneed and how they fit together. There are important aspects of app design that this guide does not cover,such as user interface design. However, this guide includes many links to other documents that provide detailsabout the technologies it introduces, as well as links to tutorials that provide a hands-on approach.

In addition, this guide emphasizes certain technologies introduced in Mac OS X v10.7, which provide essentialcapabilities that set your app apart from older ones and give it remarkable ease of use, bringing some of thebest features from iOS to Mac OS X.

See AlsoThe following documents provide additional information about designing Mac OS X apps, as well as moredetails about topics covered in this document:

● To work through a tutorial showing you how to create a Cocoa app, see Your First Mac App .

● For information about user interface design enabling you to create effective apps using Mac OS X, seeMac OS X Human Interface Guidelines .

● To understand how to create an explicit app ID, create provisioning profiles, and enable the correctentitlements for your application, so you can sell your application through the Mac App Store or use iCloudstorage, see Tools Workflow Guide for Mac .

● For information about the design patterns used in Cocoa, see Cocoa Fundamentals Guide .

● For a general survey of Mac OS X technologies, see Mac OS X Technology Overview .

● To understand how to implement a document-based app, see Document-Based App Programming Guidefor Mac .

About Mac OS X App DesignHow to Use This Document

2012-01-09 | © 2012 Apple Inc. All Rights Reserved.

9

Page 10: Mos x App Programming Guide

Mac OS X incorporates the latest technologies for creating powerful and fun-to-use apps. But the technologiesby themselves are not enough to make every app great. What sets an app apart from its peers is how it helpsthe user achieve some tangible goal. After all, users are not going to care what technologies an app uses, aslong as it helps them do what they need to do. An app that gets in the user’s way is going to be forgotten,but one that makes work (or play) easier and more fun is going to be remembered.

You use Cocoa to write apps for Mac OS X. Cocoa gives you access to all of the features of Mac OS X and allowsyou to integrate your app cleanly with the rest of the system. This chapter covers the key parts of Mac OS Xthat help you create great apps. In particular, this chapter describes some of the important ease-of-usetechnologies introduced in Mac OS X v10.7. For a more thorough list of technologies available in Mac OS X,see Mac OS X Technology Overview .

An Environment Designed for Ease of UseMac OS X strives to provide an environment that is transparent to users and as easy to use as possible. Bymaking hard tasks simple and getting out of the way, the system makes it easier for the user to be creativeand spend less time worrying about the steps needed to make the computer work. Of course, simplifying tasksmeans your app has to do more of the work, but Mac OS X provides help in that respect too.

As you design your app, you should think about the tasks that users normally perform and find ways to makethem easier. Mac OS X supports powerful ease-of-use features and design principles. For example:

● Users should not have to save their work manually. The document model in Cocoa provides support forsaving the user’s file-based documents without user interaction; see “The Document Architecture ProvidesMany Capabilities for Free” (page 31).

● Apps should restore the user’s work environment at login time. Cocoa provides support for archiving thecurrent state of the app’s interface (including the state of unsaved documents) and restoring that state atlaunch time; see “User Interface Preservation” (page 38).

● Apps should support automatic termination so that the user never has to quit them. Automatic terminationmeans that when the user closes an app’s windows, the app appears to quit but actually just moves tothe background quietly. The advantage is that subsequent launches are nearly instant as the app simplymoves back to the foreground; see “Automatic and Sudden Termination of Apps Improve the UserExperience” (page 35)

2012-01-09 | © 2012 Apple Inc. All Rights Reserved.

10

The Mac Application Environment

Page 11: Mos x App Programming Guide

● You should consider providing your users with an immersive, full-screen experience by implementing afull-screen version of your user interface. The full-screen experience eliminates outside distractions andallows the user to focus on their content; see “Implementing the Full-Screen Experience” (page 66).

● Support trackpad gestures for appropriate actions in your app. Gestures provide simple shortcuts forcommon tasks and can be used to supplement existing controls and menu commands. Mac OS X providesautomatic support for reporting gestures to your app through the normal event-handling mechanism;see Cocoa Event-Handling Guide .

● Consider minimizing or eliminating the user’s interactions with the raw file system. Rather than exposethe entire file system to the user through the open and save panels, some apps, in the manner of iPhotoand iTunes, can provide a better user experience by presenting the user’s content in a simplified browserdesigned specifically for the app’s content. Mac OS X uses a well-defined file system structure that allowsyou to place and find files easily and includes many technologies for accessing those files; see “The FileSystem” (page 13).

● For apps that support custom document types, provide a Quick Look plug-in so that users can view yourdocuments from outside of your app; see Quick Look Programming Guide .

● Apps should support the fundamental features for the Mac OS X user experience that make apps elegantand intuitive, such as direct manipulation and drag-and-drop. Users should remain in control, receiveconsistent feedback, and be able to explore because the app is forgiving with reversible actions; see MacOS X Human Interface Guidelines .

All of the preceding features are supported by Cocoa and can be incorporated with relatively little effort.

A Sophisticated Graphics EnvironmentHigh-quality graphics and animation make your app look great and can convey a lot of information to the user.Animations in particular are a great way to provide feedback about changes to your user interface. So as youdesign your app, keep the following ideas in mind:

● Use animations to provide feedback and convey changes. Cocoa provides mechanisms for creatingsophisticated animations quickly in both the AppKit and Core Animation frameworks. For informationabout creating view-based animations, see Cocoa Drawing Guide . For information about using CoreAnimation to create your animations, see Core Animation Programming Guide .

● Include high-resolution versions of your art and graphics. Mac OS X automatically loads high-resolutionimage resources when an app runs on a screen whose scaling factor is greater than 1.0. Including suchimage resources makes your app’s graphics look even sharper and crisper on those higher-resolutionscreens.

The Mac Application EnvironmentA Sophisticated Graphics Environment

2012-01-09 | © 2012 Apple Inc. All Rights Reserved.

11

Page 12: Mos x App Programming Guide

For information about the graphics technologies available in Mac OS X, see “Media Layer” inMacOSX TechnologyOverview .

Low-Level Details of the Runtime EnvironmentWhen you are ready to begin writing actual code, there are a lot of technologies available to make your lifeeasier. Mac OS X supports all of the basic features such as memory management, file management, networking,and concurrency that you need to write your code. In some cases, though, Mac OS X also provides moresophisticated services (or specific coding conventions) that, when followed, can make writing your code eveneasier.

Based on UNIXMac OS X is powered by a 64-bit Mach kernel, which manages processor resources, memory, and other low-levelbehaviors. On top of the kernel sits a modified version of the Berkeley Software Distribution (BSD) operatingsystem, which provides interfaces that apps can use to interact with the lower-level system. This combinationof Mach and BSD provides the following system-level support for your apps:

● Preemptive multitasking—All processes share the CPU efficiently. The kernel schedules processes in away that ensures they all receive the time they need to run. Even background apps continue to receiveCPU time to execute ongoing tasks.

● Protected memory—Each process runs in its own protected memory space, which prevents processesfrom accidentally interfering with each other. (Apps can share part of their memory space to implementfast interprocess communication but take responsibility for synchronizing and locking that memoryappropriately.)

● Virtual memory—64-bit apps have a virtual address space of approximately 18 exabytes (18 billion billionbytes). (If you create a 32-bit app, the amount of virtual memory is only 4 GB.) When an app’s memoryusage exceeds the amount of free physical memory, the system transparently writes pages to disk to makemore room. Written out pages remain on disk until they are needed in memory again or the app exits.

● Networking and Bonjour—Mac OS X provides support for the standard networking protocols and servicesin use today. BSD sockets provide the low-level communication mechanism for apps, but higher-levelinterfaces also exist. Bonjour simplifies the user networking experience by providing a dynamic way toadvertise and connect to network services over TCP/IP.

For detailed information about the underlying environment of Mac OS X, see “Kernel and Device Drivers Layer”

in Mac OS X Technology Overview .

The Mac Application EnvironmentLow-Level Details of the Runtime Environment

2012-01-09 | © 2012 Apple Inc. All Rights Reserved.

12

Page 13: Mos x App Programming Guide

Concurrency and ThreadingEach process starts off with a single thread of execution and can create more threads as needed. Although youcan create threads directly using POSIX and other higher-level interfaces, for most types of work it is better tocreate them indirectly using block objects with Grand Central Dispatch (GCD) or operation objects, a Cocoaconcurrency technology implemented by the NSOperation class.

GCD and operation objects are an alternative to raw threads that simplify or eliminate many of the problemsnormally associated with threaded programming, such as synchronization and locking. Specifically, they definean asynchronous programming model in which you specify only the work to be performed and the order inwhich you want it performed. The system then handles the tedious work required to schedule the necessarythreads and execute your tasks as efficiently as possible on the current hardware. You should not use GCD oroperations for work requiring time-sensitive data processing (such as audio or video playback), but you canuse them for most other types of tasks.

For more information on using GCD and operation objects to implement concurrency in your apps, seeConcurrency Programming Guide .

The File SystemThe file system in Mac OS X is structured to provide a better experience for users. Rather than exposing theentire file system to the user, the Finder hides any files and directories that an average user should not needto use, such as the contents of low-level UNIX directories. This is done to provide a simpler interface for theend user (and only in places like the Finder and the open and save panels). Apps can still access any files anddirectories for which they have valid permissions, regardless of whether they are hidden by the Finder.

When creating apps, you should understand and follow the conventions associated with the Mac OS X filesystem. Knowing where to put files and how to get information out of the file system ensures a better userexperience.

A Few Important App DirectoriesThe Mac OS X file system is organized in a way that groups related files and data together in specific places.Every file in the file system has its place and apps need to know where to put the files they create. This isespecially important if you are distributing your app through the App Store, which expects you to put yourapp’s data files in specific directories.

Table 1-1 lists the directories with which apps commonly interact. Directories preceded with a tilde (~) characterindicate a path inside the home directory, which can be either the user’s home directory or the app’s containerdirectory if the app is in a sandbox (as described in “App Sandbox and XPC” (page 18)). Because the actualpaths can differ based on the conditions, use the URLsForDirectory:inDomains: method of theNSFileManager class to retrieve the actual directory path. You can then add any custom directory and filenameinformation to the returned URL object to complete the path.

The Mac Application EnvironmentLow-Level Details of the Runtime Environment

2012-01-09 | © 2012 Apple Inc. All Rights Reserved.

13

Page 14: Mos x App Programming Guide

Table 1-1 Key directories for Mac OS X apps

DescriptionDirectory

This is the installation directory for your app bundle. The path for the global Applicationsdirectory is /Applications but each user directory may have a local applications directorycontaining user-specific apps. Regardless, you should not need to use this path directly.To access resources inside your application bundle, use an NSBundle object instead.

For more information about the structure of your application bundle and how youlocate resources, see “The Mac OS X Application Bundle” (page 81).

Applicationsdirectory

The configuration of your app determines the location of the home directory seen byyour app:

● For apps running in a sandbox in Mac OS X 10.7 and later, the home directory isthe app’s container directory. For more information about the container directory,see “The Keychain” (page 20).

● For apps running outside of a sandbox (including those running in versions ofMac OS X before 10.7), the home directory is the user-specific subdirectory of/Users that contains the user’s files.

To retrieve the path to the home directory, use the NSHomeDirectory function.

Homedirectory

The Library directory is the top-level directory for storing private app-related data andpreferences. There are several Library directories scattered throughout the system butyou should always use the one located inside the current home directory.

Do not store files directly at the top-level of the Library directory. Instead, store themin one of the specific subdirectories described in this table.

In Mac OS X 10.7 and later, the Finder hides the Library directory in the user’s homefolder by default. Therefore, you should never store files in this directory that you wantthe user to access.

To get the path to this directory use the NSLibraryDirectory search path key withthe NSUserDomainMask domain.

Librarydirectory

The Mac Application EnvironmentLow-Level Details of the Runtime Environment

2012-01-09 | © 2012 Apple Inc. All Rights Reserved.

14

Page 15: Mos x App Programming Guide

DescriptionDirectory

The Application Support directory is where your app stores any type of file that supportsthe app but is not required for the app to run, such as document templates orconfiguration files. The files should be app-specific but should never store user data.This directory is located inside the Library directory.

Never store files at the top level of this directory: Always put them in a subdirectorynamed for your app or company.

If the resources apply to all users on the system, such as document templates, placethem in /Library/Application Support. To get the path to this directory use theNSApplicationSupportDirectory search path key with the NSLocalDomainMaskdomain. If the resources are user-specific, such as workspace configuration files, placethem in the current user’s ~/Library/Application Support directory. To get the path tothis directory use the NSApplicationSupportDirectory search path key with theNSUserDomainMask domain.

ApplicationSupportdirectory

The Caches directory is where you store cache files and other temporary data thatyour app can re-create as needed. This directory is located inside the Library directory.

Never store files at the top level of this directory: Always put them in a subdirectorynamed for your app or company. Your app is responsible for cleaning out cache datafiles when they are no longer needed. The system does not delete files from thisdirectory.

To get the path to this directory use the NSCachesDirectory search path key withthe NSUserDomainMask domain.

Cachesdirectory

The Movies directory contains the user’s video files.

To get the path to this directory use the NSMoviesDirectory search path key withthe NSUserDomainMask domain.

Moviesdirectory

The Music directory contains the user’s music and audio files.

To get the path to this directory use the NSMusicDirectory search path key withthe NSUserDomainMask domain.

Musicdirectory

The Pictures directory contains the user’s images and photos.

To get the path to this directory use the NSPicturesDirectory search path keywith the NSUserDomainMask domain.

Picturesdirectory

The Mac Application EnvironmentLow-Level Details of the Runtime Environment

2012-01-09 | © 2012 Apple Inc. All Rights Reserved.

15

Page 16: Mos x App Programming Guide

DescriptionDirectory

The Temporary directory is where you store files that do not need to persist betweenlaunches of your app. You normally use this directory for scratch files or other typesof short-lived data files that are not related to your app’s persistent data. This directoryis typically hidden from the user.

Your app should remove files from this directory as soon as it is done with them. Thesystem may also purge lingering files from this directory at system startup.

To get the path to this directory use the NSTemporaryDirectory function.

Temporarydirectory

Listing 1-1 shows an example of how to retrieve the base path to the Application Support directory andthen append a custom app directory to it.

Listing 1-1 Getting the path to the Application Support directory

NSFileManager* fileManager = [NSFileManager defaultManager];

NSURL* appSupportDir = nil;

NSArray *urls = [fileManager URLsForDirectory:NSApplicationSupportDirectory inDomains:NSUserDomainMask];

if ([paths count] > 0) {

appSupportDir = [[urls objectAtIndex:0] URLByAppendingPathComponent:@"com.example.MyApp"];

}

For more information about how to access files in well known system directories, see File System ProgrammingGuide .

Coordinating File Access with Other ProcessesIn Mac OS X, other processes may have access to the same files that your app does. Therefore, when workingwith files, you should use the file coordination interfaces introduced in Mac OS X v10.7 to be notified whenother processes (including the Finder) attempt to read or modify files your app is currently using. For example,coordinating file access is critical when your app adopts iCloud storage.

The file coordination APIs allow you to assert ownership over files and directories that your app cares about.Any time another process attempts to touch one of those items, your app is given a chance to respond. Forexample, when an app attempts to read the contents of a document your app is editing, you can write unsavedchanges to disk before the other process is allowed to do its reading.

The Mac Application EnvironmentLow-Level Details of the Runtime Environment

2012-01-09 | © 2012 Apple Inc. All Rights Reserved.

16

Page 17: Mos x App Programming Guide

Using iCloud document storage, for example, you must incorporate file coordination because multiple appscan access your document files in iCloud. The simplest way to incorporate file coordination into your app is touse the NSDocument class, which handles all of the file-related management for you. See Document-BasedApp Programming Guide for Mac .

On the other hand, if you're writing a library-style (or “shoebox”) app, you must use the file coordinationinterfaces directly, as described in File System Programming Guide .

Interacting with the File SystemDisks in Macintosh computers are formatted using the HFS+ file system by default. However, Macintoshcomputers can interact with disks that use other formats so you should never code specifically to any one filesystem. Table 1-2 lists some of the basic file system attributes you may need to consider in your app and howyou should handle them.

Table 1-2 Attributes for the Mac OS X file system

DescriptionAttribute

The HFS+ file system is case-insensitive but also case-preserving. Therefore, whenspecifying filenames and directories in your code, it is best to assume case-sensitivity.

Case sensitivity

Construct paths using the methods of the NSURL and NSString classes. The NSURLclass is preferred for path construction because of its ability to specify not only pathsin the local file system but paths to network resources.

Pathconstruction

Many file-related attributes can be retrieved using the getResourceValue:forKey:error: method of the NSURL class. You can also use an NSFileManagerobject to retrieve many file-related attributes.

File attributes

File permissions are managed using access control lists (ACLs) and BSD permissions.The system uses ACLs whenever possible to specify precise permissions for files anddirectories, but it falls back to using BSD permissions when no ACLs are specified.

By default, any files your app creates are owned by the current user and givenappropriate permissions. Thus, your app should always be able to read and writefiles it creates explicitly. In addition, the app’s sandbox may allow it to access otherfiles in specific situations. For more information about the sandbox, see “App Sandboxand XPC” (page 18).

File permissions

Apps that cannot use the File Coordination interfaces (see “Coordinating File Accesswith Other Processes” (page 16)) to track changes to files and directories can usethe FSEvents API instead. This API provides a lower-level interface for tracking filesystem interactions and is available in Mac OS X v10.5 and later.

For information on how to use the FSEvents API, see File SystemEvents ProgrammingGuide .

Tracking filechanges

The Mac Application EnvironmentLow-Level Details of the Runtime Environment

2012-01-09 | © 2012 Apple Inc. All Rights Reserved.

17

Page 18: Mos x App Programming Guide

SecurityThe security technologies in Mac OS X help you safeguard sensitive data created or managed by your app, andhelp minimize damage caused by successful attacks from hostile code. These technologies impact how yourapp interacts with system resources and the file system.

App Sandbox and XPCYou secure your app against attack from malware by following the practices recommended in Secure CodingGuide . But an attacker needs only to find a single hole in your defenses, or in any of the frameworks and librariesthat you link against, to gain control of your app along with all of its privileges.

Starting in Mac OS X v10.7, App Sandbox provides a last line of defense against stolen, corrupted, or deleteduser data if malicious code exploits your app. App Sandbox also minimizes the damage from coding errors. Itsstrategy is twofold:

1. App Sandbox enables you to describe how your app interacts with the system. The system then grantsyour app the access it needs to get its job done, and no more. For your app to provide the highest levelof damage containment, the best practice is to adopt the tightest sandbox possible.

2. App Sandbox allows the user to transparently grant your app additional access by way of Open and Savedialogs, drag and drop, and other familiar user interactions.

You describe your app’s interaction with the system by way of setting entitlements in Xcode. An entitlementis a key-value pair, defined in a property list file, that confers a specific capability or security permission to atarget. For example, there are entitlement keys to indicate that your app needs access to the camera, thenetwork, and user data such as the Address Book. For details on all the entitlements available in Mac OS X, seeEntitlement Key Reference .

When you adopt App Sandbox, the system provides a special directory for use by your app—and only by yourapp—called a container. Your app has unfettered read/write access to the container. All Mac OS X path-findingAPIs, above the POSIX layer, are relative to the container instead of to the user’s home directory. Other sandboxedapps have no access to your app’s container, as described further in “Code Signing” (page 19).

The Mac Application EnvironmentLow-Level Details of the Runtime Environment

2012-01-09 | © 2012 Apple Inc. All Rights Reserved.

18

Page 19: Mos x App Programming Guide

iOS Note Because it is not for user documents, a Mac OS X container differs from an iOS containerwhich, in iOS, is the one and only location for user documents. As the sole local location for userdocuments, an iOS container is usually known simply as an app’s Documents directory.

In addition, an iOS container contains the app itself. This is not so in Mac OS X.

iCloud Note Apple’s iCloud technology, as described in “iCloud Storage” (page 49), uses the name“container” as well. There is no functional connection between an iCloud container and an AppSandbox container.

Your sandboxed app can access paths outside of its container in the following three ways:

● At the specific direction of the user

● By you configuring your app with entitlements for specific file-system locations, such as the Movies folder

● When a path is in any of certain directories that are world readable

The Mac OS X security technology that interacts with the user to expand your sandbox is called Powerbox.Powerbox has no API. Your app uses Powerbox transparently when, for example, you use the NSOpenPaneland NSSavePanel classes, or when the user employs drag and drop with your app.

Some app operations are more likely to be targets of malicious exploitation. Examples are the parsing of datareceived over a network, and the decoding of video frames. By using XPC, you can improve the effectivenessof the damage containment offered by App Sandbox by separating such potentially dangerous activities intotheir own address spaces.

XPC is a Mac OS X interprocess communication technology that complements App Sandbox by enablingprivilege separation. Privilege separation, in turn, is a development strategy in which you divide an app intopieces according to the system resource access that each piece needs. The component pieces that you createare called XPC services . For details on adopting XPC, see Daemons and Services Programming Guide .

For a complete explanation of App Sandbox and how to use it, read App Sandbox Design Guide .

Code SigningMac OS X employs the security technology known as code signing to allow you to certify that your app wasindeed created by you. After an app is code signed, the system can detect any change to the app—whetherthe change is introduced accidentally or by malicious code. Various security technologies, including AppSandbox and parental controls, depend on code signing.

The Mac Application EnvironmentLow-Level Details of the Runtime Environment

2012-01-09 | © 2012 Apple Inc. All Rights Reserved.

19

Page 20: Mos x App Programming Guide

In most cases, you can rely on Xcode’s automatic code signing, which requires only that you specify a codesigning identity in the build settings for your project. The steps to take are described in “Code Signing Your App”

in Tools Workflow Guide for Mac . If you need to incorporate code signing into an automated build system, orif you link your app against third-party frameworks, refer to the procedures described in Code Signing Guide .

When you adopt App Sandbox, you must code sign your app. This is because entitlements (including thespecial entitlement that enables App Sandbox) are built into an app’s code signature.

Mac OS X enforces a tie between an app’s container and the app’s code signature. This important securityfeature ensures that no other sandboxed app can access your container. The mechanism works as follows:After the system creates a container for an app, each time an app with the same bundle ID launches, the systemchecks that the app’s code signature matches a code signature expected by the container. If the system detectsa mismatch, it prevents the app from launching.

For a complete explanation of code signing in the context of App Sandbox, read “App Sandbox in Depth” in AppSandbox Design Guide .

The KeychainA keychain is a secure, encrypted container for storing a user’s passwords and other secrets. It is designed tohelp a user manage their multiple logins, each with its own ID and password. You should always use keychainto store sensitive credentials for your app.

For more on the keychain, see “Keychain Services Concepts” in Keychain Services Programming Guide .

The Mac Application EnvironmentLow-Level Details of the Runtime Environment

2012-01-09 | © 2012 Apple Inc. All Rights Reserved.

20

Page 21: Mos x App Programming Guide

To unleash the power of Mac OS X, you develop apps using the Cocoa application environment. Cocoa presentsthe app’s user interface and integrates it tightly with the other components of the operating system. Cocoaprovides an integrated suite of object-oriented software components packaged in two core class libraries, theAppKit and Foundation frameworks, and a number of underlying frameworks providing supporting technologies.Cocoa classes are reusable and extensible—you can use them as is or extend them for your particularrequirements.

Cocoa makes it easy to create apps that adopt all of the conventions and expose all of the power of OS X. Infact, you can create a new Cocoa application project in Xcode and without adding any code have a functionalapp. Such an app is able to display its window (or create new documents) and implements many standardsystem behaviors. And although the Xcode templates provide some code to make this all happen, the amountof code they provide is minimal. Most of the behavior is provided by Cocoa.

To make a great app, you should build on the foundations Cocoa lays down for you, working with theconventions and infrastructure provided for you. To do so effectively, it's important to understand how a Cocoaapp fits together.

Fundamental Design PatternsCocoa incorporates many design patterns in its implementation. Table 2-1 lists the key design patterns withwhich you should be familiar.

Table 2-1 Fundamental design patterns used by Mac OS X apps

Why it is importantDesign pattern

Use of the Model-View-Controller (MVC) design pattern ensures that theobjects you create now can be reused or updated easily in future versions ofyour app.

Cocoa provides most of the classes used to build your app’s controller andview layers. It is your job to customize the classes you need and provide thenecessary data model objects to go with them.

MVC is central to a good design for a Cocoa application because many Cocoatechnologies and architectures are based on MVC and require that your customobjects assume one of the MVC roles.

Model-View-Controller

2012-01-09 | © 2012 Apple Inc. All Rights Reserved.

21

The Core App Design

Page 22: Mos x App Programming Guide

Why it is importantDesign pattern

The delegation design pattern allows you to change the runtime behavior ofan object without subclassing. Delegate objects conform to a specific protocolthat defines the interaction points between the delegate and the object itmodifies. At specific points, the master object calls the methods of its delegateto provide it with information or ask what to do. The delegate can then takewhatever actions are appropriate.

Delegation

The responder chain defines the relationships between event-handling objectsin your app. As events arrive, the app dispatches them to the first responderobject for handling. If that object does not want the event, it passes it to thenext responder, which can either handle the event or send it to its nextresponder, and so on up the chain.

Windows and views are the most common types of responder objects and arealways the first responders for mouse events. Other types of objects, such asyour app’s controller objects, may also be responders.

Responder chain

Controls use the target-action design pattern to notify your app of userinteractions. When the user interacts with a control in a predefined way (suchas by touching a button), the control sends a message (the action) to an objectyou specify (the target). Upon receiving the action message, the target objectcan then respond in an appropriate manner.

Target-action

Block objects are a convenient way to encapsulate code and local stackvariables in a form that can be executed later. Blocks are used in lieu of callbackfunctions by many frameworks and are also used in conjunction with GrandCentral Dispatch to perform tasks asynchronously.

For more information about using blocks, see Blocks Programming Topics .

Block objects

Notifications are used throughout Cocoa to deliver news of changes to yourapp. Many objects send notifications at key moments in the object’s life cycle.Intercepting these notifications gives you a chance to respond and add custombehavior.

Notifications

KVO tracks changes to a specific property of an object. When that propertychanges, the change generates automatic notifications for any objects thatregistered an interest in that property. Those observers then have a chance torespond to the change.

Key-value observing(KVO)

The Core App DesignFundamental Design Patterns

2012-01-09 | © 2012 Apple Inc. All Rights Reserved.

22

Page 23: Mos x App Programming Guide

Why it is importantDesign pattern

Cocoa bindings provide a convenient bridge between the model, view, andcontroller portions of your app. You bind a view to some underlying data object(which can be static or dynamic) through one of your controllers. Changes tothe view are then automatically reflected in the data object, and vice versa.

The use of bindings is not required for apps but does minimize the amount ofcode you have to write. You can set up bindings programmatically or usingInterface Builder.

Bindings

For a more detailed discussion of Cocoa and the design patterns you use to implement Mac OS X apps, seeCocoa Fundamentals Guide .

The App Style Determines the Core ArchitectureThe style of your app defines which core objects you must use in its implementation. Cocoa supports thecreation of both single-window and multiwindow apps. For multiwindow designs, it also provides a documentarchitecture to help manage the files associated with each app window. Thus, apps can have the followingforms:

● Single-window utility app

● Single-window library-style app

● Multiwindow document-based app

You should choose a basic app style early in your design process because that choice affects everything youdo later. The single-window styles are preferred in many cases, especially for developers bringing apps fromiOS. The single-window style typically yields a more streamlined user experience, and it also makes it easierfor your app to support a full-screen mode. However, if your app works extensively with complex documents,the multiwindow style may be preferable because it provides more document-related infrastructure to helpyou implement your app.

The Core App DesignThe App Style Determines the Core Architecture

2012-01-09 | © 2012 Apple Inc. All Rights Reserved.

23

Page 24: Mos x App Programming Guide

The Calculator app provided with Mac OS X, shown in Figure 2-1, is an example of a single-window utility app.Utility apps typically handle ephemeral data or manage system processes. Calculator does not create or dealwith any documents or persistent user data but simply processes numerical data entered by the user into thetext field in its single window, displaying the results of its calculations in the same field. When the user quitsthe app, the data it processed is simply discarded.

Figure 2-1 The Calculator single-window utility app

Single-window, library-style (or “shoebox”) apps do handle persistent user data. One of the most prominentexamples of a library-style app is iPhoto, shown in Figure 2-2. The user data handled by iPhoto are photos (andassociated metadata), which the app edits, displays, and stores. All user interaction with iPhoto happens in asingle window. Although iPhoto stores its data in files, it doesn’t present the files to the user. The app presentsa simplified interface so that users don’t need to manage files in order to use the app. Instead, they workdirectly with their photos. Moreover, iPhoto hides its files from regular manipulation in the Finder by placing

The Core App DesignThe App Style Determines the Core Architecture

2012-01-09 | © 2012 Apple Inc. All Rights Reserved.

24

Page 25: Mos x App Programming Guide

them within a single package. In addition, the app saves the user’s editing changes to disk at appropriate times.So, users are relieved of the need to manually save, open, or close documents. This simplicity for users is oneof the key advantages of the library-style app design.

Figure 2-2 The iPhoto single-window app

A good example of a multiwindow document-based app is TextEdit, which creates, displays, and edits documentscontaining plain or styled text and images. TextEdit does not organize or manage its documents—users dothat with the Finder. Each TextEdit document opens in its own window, multiple documents can be open at

The Core App DesignThe App Style Determines the Core Architecture

2012-01-09 | © 2012 Apple Inc. All Rights Reserved.

25

Page 26: Mos x App Programming Guide

one time, and the user interacts with the frontmost document using controls in the window’s toolbar and theapp’s menu bar. Figure 2-3 shows a document created by TextEdit. For more information about thedocument-based app design, see “Document-Based Apps Are Based on an NSDocument Subclass” (page 30).

Figure 2-3 TextEdit document window

Both single-window and multiwindow apps can present an effective full-screen mode, which provides animmersive experience that enables users to focus on their tasks without distractions. For information aboutfull-screen mode, see “Implementing the Full-Screen Experience” (page 66).

The Core Objects for All Cocoa AppsRegardless of whether you are using a single-window or multiwindow app style, all apps use the same coreset of objects. Cocoa provides the default behavior for most of these objects. You are expected to provide acertain amount of customization of these objects to implement your app’s custom behavior.

The Core App DesignThe App Style Determines the Core Architecture

2012-01-09 | © 2012 Apple Inc. All Rights Reserved.

26

Page 27: Mos x App Programming Guide

Figure 2-4 shows the relationships among the core objects for the single-window app styles. The objects inthis figure are separated according to whether they are part of the model, view, or controller portions of the app.As you can see from the figure, the Cocoa–provided objects provide much of the controller and view layer foryour app.

Figure 2-4 Key objects in a single-window app

Data Model ObjectsData Model ObjectsData Model Objects

Data Model ObjectsData Model ObjectsViews and UI ObjectsData Model ObjectsData Model ObjectsView controllers

(optional)

Model

Controller

EventLoop

View

NSWindow

NSApplication Application Delegate

Window Controller

Table 2-2 (page 27) describes the roles played by the objects in the diagram.

Table 2-2 The core objects used by all Cocoa apps

DescriptionObject

(Required) Runs the event loop and manage interactions between your app andthe system. You typically use the NSApplication class as is, putting any customapp-object-related code in your application delegate object.

NSApplicationobject

(Expected) A custom object that you provide which works closely with theNSApplication object to run the app and manage the transitions betweendifferent application states.

Your application delegate object must conform to the NSApplicationDelegateProtocol.

Applicationdelegate object

Store content specific to your app. A banking app might store a databasecontaining financial transactions, whereas a painting app might store an imageobject or the sequence of drawing commands that led to the creation of thatimage.

Data modelobjects

The Core App DesignThe App Style Determines the Core Architecture

2012-01-09 | © 2012 Apple Inc. All Rights Reserved.

27

Page 28: Mos x App Programming Guide

DescriptionObject

Responsible for loading and managing a single window each and coordinatingwith the system to handle standard window behaviors.

You subclassNSWindowController to manage both the window and its contents.Each window controller is responsible for everything that happens in its window.If the contents of your window are simple, the window controller may do all ofthe management itself. If your window is more complex, the window controllermight use one or more view controllers to manage portions of the window.

Windowcontrollers

Represent your onscreen windows, configured in different styles depending onyour app’s needs. For example, most windows have title bars and borders but youcan also configure windows without those visual adornments. A window objectis almost always managed by a window controller.

An app can also have secondary windows, also known as dialogs and panels. Thesewindows are subordinate to the current document window or, in the case ofsingle-window apps, to the main window. They support the document or mainwindow, for example, allowing selection of fonts and color, allowing the selectionof tools from a palette, or displaying a warning‚ A secondary window is oftenmodal.

Window objects

Coordinate the loading of a single view hierarchy into your app. Use viewcontrollers to divide up the work for managing more sophisticated window layouts.Your view controllers work together (with the window controller) to present thewindow contents.

If you have developed iOS apps, be aware that AppKit view controllers play a lessprominent role than UIKit view controllers. In Mac OS X, AppKit view controllersare assistants to the window controller, which is ultimately responsible foreverything that goes in the window. The main job of an AppKit view controller isto load its view hierarchy. Everything else is custom code that you write.

View controllers

Define a rectangular region in a window, draw the contents of that region, andhandle events in that region. Views can be layered on top of each other to createview hierarchies, whereby one view obscures a portion of the underlying view.

View objects

Represent standard system controls. These view subclasses provide standard visualitems such as buttons, text fields, and tables that you can use to build your userinterface. Although a few controls are used as is to present visual adornments,most work with your code to manage user interactions with your app’s content.

Control objects

The Core App DesignThe App Style Determines the Core Architecture

2012-01-09 | © 2012 Apple Inc. All Rights Reserved.

28

Page 29: Mos x App Programming Guide

Additional Core Objects for Multiwindow AppsAs opposed to a single-window app, a multiwindow app uses several windows to present its primary content.The Cocoa support for multiwindow apps is built around a document-based model implemented by a subsystemcalled the document architecture. In this model, each document object manages its content, coordinates thereading and writing of that content from disk, and presents the content in a window for editing. All documentobjects work with the Cocoa infrastructure to coordinate event delivery and such, but each document objectis otherwise independent of its fellow document objects.

Figure 2-5 shows the relationships among the core objects of a multiwindow document-based app. Many ofthe same objects in this figure are identical to those used by a single-window app. The main difference is theinsertion of the NSDocumentController and NSDocument objects between the application objects and theobjects for managing the user interface.

Figure 2-5 Key objects in a multiwindow document app

Data model objects

NSWindowViews and UI objects

View

Window controller

Model

Controller

Eventloop

NSApplication

NSDocument

View controllers (optional)

Application delegate

NSDocumentController

The Core App DesignThe App Style Determines the Core Architecture

2012-01-09 | © 2012 Apple Inc. All Rights Reserved.

29

Page 30: Mos x App Programming Guide

Table 2-3 (page 30) describes the role of the insertedNSDocumentController and NSDocument objects.(For information about the roles of the other objects in the diagram, see Table 2-2 (page 27).)

Table 2-3 Additional objects used by multiwindow document apps

DescriptionObject

The NSDocumentController class defines a high-level controller for creatingand managing all document objects. In addition to managing documents, thedocument controller also manages many document-related menu items, such asthe Open Recent menu and the open and save panels.

DocumentController object

The NSDocument class is the base class for implementing documents in amultiwindow app. This class acts as the controller for the data objects associatedwith the document. You define your own custom subclasses to manage theinteractions with your app’s data objects and to work with one or moreNSWindowController objects to display the document contents on the screen.

Document object

Library-Style Apps Should Not Use NSDocumentWhen implementing a single-window, library-style (or “shoebox”) app, it is better not to use NSDocumentobjects to manage your content. The NSDocument class was designed specifically for use in multiwindowdocument apps. Instead, use custom controller objects to manage your data. Those custom controllers wouldthen work with a view controller or your app’s main window controller to coordinate the presentation of thedata.

Although you normally use an NSDocumentController object only in multiwindow apps, you can subclassit and use it in a single-window app to coordinate the Open Recent and similar behaviors. When subclassing,though, you must override any methods related to the creation of NSDocument objects.

Document-Based Apps Are Based on an NSDocument SubclassDocuments are containers for user data that can be stored in files and iCloud. In a document-based design,the app enables users to create and manage documents containing their data. One app typically handlesmultiple documents, each in its own window, and often displays more than one document at a time. Forexample, a word processor provides commands to create new documents, it presents an editing environmentin which the user enters text and embeds graphics into the document, it saves the document data to disk (and,optionally, iCloud), and it provides other document-related commands, such as printing and versionmanagement. In Cocoa, the document-based app design is enabled by the document architecture, which ispart of of the AppKit framework.

The Core App DesignDocument-Based Apps Are Based on an NSDocument Subclass

2012-01-09 | © 2012 Apple Inc. All Rights Reserved.

30

Page 31: Mos x App Programming Guide

Documents in Mac OS XThere are several ways to think of a document. Conceptually, a document is a container for a body of informationthat can be named and stored in a disk file and in iCloud. In this sense, the document is not the same as thefile but is an object in memory that owns and manages the document data. To users, the document is theirinformation—such as text and graphics formatted on a page. Programmatically, a document is an instance ofa custom NSDocument subclass that knows how to represent internally persistent data that it can display inwindows. This document object knows how to read document data from a file and create an object graph inmemory for the document data model. It also knows how to handle the user’s editing commands to modifythe data model and write the document data back out to disk. So, the document object mediates betweendifferent representations of document data, as shown in Figure 2-6.

Figure 2-6 Document file, object, and data model

Document

Model

ModelModel

ModelDocument

File

Using iCloud, documents can be shared automatically among a user’s computers and iOS devices. Changes tothe document data are synchronized without user intervention. For information about iCloud, see “iCloudStorage” (page 49).

The Document Architecture Provides Many Capabilities for FreeThe document-based style of app is a design choice that you should consider when you design your app. If itmakes sense for your users to create multiple discrete sets of data, each of which they can edit in a graphicalenvironment and store in files or iCloud, then you certainly should plan to develop a document-based app.

The Cocoa document architecture provides a framework for document-based apps to do the following things:

● Create new documents. The first time the user chooses to save a new document, it presents a dialogenabling the user to name and save the document in a disk file in a user-chosen location.

The Core App DesignDocument-Based Apps Are Based on an NSDocument Subclass

2012-01-09 | © 2012 Apple Inc. All Rights Reserved.

31

Page 32: Mos x App Programming Guide

● Open existing documents stored in files. A document-based app specifies the types of document it canread and write, as well as read-only and write-only types. It can represent the data of different typesinternally and display the data appropriately. It can also close documents.

● Automatically save documents. Document-based apps can adopt autosaving in place, and its documentsare automatically saved at appropriate times so that the data the user sees on screen is effectively thesame as that saved on disk. Saving is done safely, so that an interrupted save operation does not leavedata inconsistent.

● Asynchronously read and write document data. Reading and writing are done asynchronously on abackground thread, so that lengthy operations do not make the app’s user interface unresponsive. Inaddition, reads and writes are coordinated using NSFilePresenter protocol and NSFileCoordinator

class to reduce version conflicts. Coordinated reads and writes reduce version conflicts both amongdifferent apps sharing document data in local storage and among different instances of an app on differentdevices sharing document data via iCloud.

● Manage multiple versions of documents. Autosave creates versions at regular intervals, and users canmanually save a version whenever they wish. Users can browse versions and revert the document’s contentsto a chosen version using a Time Machine–like interface. The version browser is also used to resolve versionconflicts from simultaneous iCloud updates.

● Print documents. The print dialog and page setup dialog enable the user to choose various page layouts.

● Monitor and set the document’s edited status and validate menu items. To avoid automatic saving ofinadvertent changes, old files are locked from editing until explicitly unlocked by the user.

● Track changes. The document manages its edited status and implements multilevel undo and redo.

● Handle app and window delegation. Notifications are sent and delegate methods called at significantlifecycle events, such as when the app terminates.

See Document-Based App Programming Guide for Mac for more detailed information about how to implementa document-based app.

The App Life CycleThe app life cycle is the progress of an app from its launch through its termination. Apps can be launched bythe user or the system. The user launches apps by double-clicking the app icon, using Launchpad, or openinga file whose type is currently associated with the app. In Mac OS X v10.7 and later, the system launches appsat user login time when it needs to restore the user’s desktop to its previous state.

The Core App DesignThe App Life Cycle

2012-01-09 | © 2012 Apple Inc. All Rights Reserved.

32

Page 33: Mos x App Programming Guide

When an app is launched, the system creates a process and all of the normal system-related data structuresfor it. Inside the process, it creates a main thread and uses it to begin executing your app’s code. At that point,your app’s code takes over and your app is running.

The main Function is the App Entry PointLike any C-based app, the main entry point for a Mac OS X app at launch time is the main function. In a MacOS X app, the main function is used only minimally. Its main job is to give control to the AppKit framework.Any new project you create in Xcode comes with a default main function like the one shown in Listing 2-1.You should normally not need to change the implementation of this function.

Listing 2-1 The main function of a Mac OS X app

#import <Cocoa/Cocoa.h>

int main(int argc, char *argv[])

{

return NSApplicationMain(argc, (const char **) argv);

}

The NSApplicationMain function initializes your app and prepares it to run. As part of the initializationprocess, this function does several things:

● Creates an instance of the NSApplication class. You can access this object from anywhere in your appusing the sharedApplication class method.

● Loads the nib file specified by the NSMainNibFile key in the Info.plist file and instantiates all of theobjects in that file. This is your app’s main nib file and should contain your application delegate and anyother critical objects that must be loaded early in the launch cycle. Any objects that are not needed atlaunch time should be placed in separate nib files and loaded later.

● Calls the run method of your application object to finish the launch cycle and begin processing events.

By the time the run method is called, the main objects of your app are loaded into memory but the app is stillnot fully launched. The run method notifies the application delegate that the app is about to launch, showsthe application menu bar, opens any files that were passed to the app, does some framework housekeeping,and starts the event processing loop. All of this work occurs on the app’s main thread with one exception. Filesmay be opened in secondary threads if the canConcurrentlyReadDocumentsOfType: class method of thecorresponding NSDocument object returns YES.

The Core App DesignThe App Life Cycle

2012-01-09 | © 2012 Apple Inc. All Rights Reserved.

33

Page 34: Mos x App Programming Guide

If your app preserves its user interface between launch cycles, Cocoa loads any preserved data at launch timeand uses it to re-create the windows that were open the last time your app was running. For more informationabout how to preserve your app’s user interface, see “User Interface Preservation” (page 38).

The App’s Main Event Loop Drives InteractionsAs the user interacts with your app, the app’s main event loop processes incoming events and dispatches themto the appropriate objects for handling. When the NSApplication object is first created, it establishes aconnection with the system window server, which receives events from the underlying hardware and transfersthem to the app. The app also sets up a FIFO event queue to store the events sent to it by the window server.The main event loop is then responsible for dequeueing and processing events waiting in the queue, as shownin Figure 2-7.

Figure 2-7 The main event loop

Main run loop

Event sourceevent

event

eventeventevent

Window ServerMach Port

Observer

The run method of the NSApplication object is the workhorse of the main event loop. In a closed loop, thismethod executes the following steps until the app terminates:

1. Services window-update notifications, which results in the redrawing of any windows that are marked as“dirty.”

2. Dequeues an event from its internal event queue using thenextEventMatchingMask:untilDate:inMode:dequeue: method and converts the event data intoan NSEvent object.

3. Dispatches the event to the appropriate target object using the sendEvent:method of NSApplication.

When the app dispatches an event, the sendEvent: method uses the type of the event to determine theappropriate target. There are two major types of input events: key events and mouse events. Key events aresent to the key window—the window that is currently accepting key presses. Mouse events are dispatchedto the window in which the event occurred.

The Core App DesignThe App Life Cycle

2012-01-09 | © 2012 Apple Inc. All Rights Reserved.

34

Page 35: Mos x App Programming Guide

For mouse events, the window looks for the view in which the event occurred and dispatches the event tothat object first. Views are responder objects and are capable of responding to any type of event. If the view isa control, it typically uses the event to generate an action message for its associated target.

The overall process for handling events is described in detail in Cocoa Event-Handling Guide .

Automatic and Sudden Termination of Apps Improve the User ExperienceIn Mac OS X v10.7 and later, the use of the Quit command to terminate an app is diminished in favor of moreuser-centric techniques. Specifically, Cocoa supports two techniques that make the termination of an apptransparent and fast:

● Automatic termination eliminates the need for users to quit an app. Instead, the system manages apptermination transparently behind the scenes, terminating apps that are not in use to reclaim neededresources such as memory.

● Sudden termination allows the system to kill an app’s process immediately without waiting for it toperform any final actions. The system uses this technique to improve the speed of operations such aslogging out of, restarting, or shutting down the computer.

Automatic termination and sudden termination are independent techniques, although both are designed toimprove the user experience of app termination. Although Apple recommends that apps support both, an appcan support one technique and not the other. Apps that support both techniques can be terminated by thesystem without the app being involved at all. On the other hand, if an app supports sudden termination butnot automatic termination, then it must be sent a Quit event, which it needs to process without displayingany user interface dialogs.

Automatic termination transfers the job of managing processes from the user to the system, which is betterequipped to handle the job. Users do not need to manage processes manually anyway. All they really need isto run apps and have those apps available when they need them. Automatic termination makes that possiblewhile ensuring that system performance is not adversely affected.

Apps must opt in to both automatic termination and sudden termination and implement appropriate supportfor them. In both cases, the app must ensure that any user data is saved well before termination can happen.And because the user does not quit an autoterminable app, such an app should also save the state of its userinterface using the built-in Cocoa support. Saving and restoring the interface state provides the user with asense of continuity between app launches.

For information on how to support for automatic termination in your app, see “Automatic Termination” (page36). For information on how to support sudden termination, see “Sudden Termination” (page 37).

The Core App DesignThe App Life Cycle

2012-01-09 | © 2012 Apple Inc. All Rights Reserved.

35

Page 36: Mos x App Programming Guide

Support the Key Runtime Behaviors in Your AppsNo matter what style of app you are creating, there are specific behaviors that all apps should support. Thesebehaviors are intended to help users focus on the content they are creating rather than focus on appmanagement and other busy work that is not part of creating their content.

Automatic TerminationAutomatic termination is a feature that you must explicitly code for in your app. Declaring support for automatictermination is easy, but apps also need to work with the system to save the current state of their user interfaceso that it can be restored later as needed. The system can “quit” an auto-terminable app at any time, so savingthis information maintains continuity for the app. Usually, the system quits the app some time after the userhas closed all of its windows. However, the system may also quit an app with open windows if the app is notcurrently on screen, perhaps because the user hid it or switched spaces.

To support automatic termination, you should do the following:

● Declare your app’s support for automatic termination, either programmatically or using an Info.plist

key.

● Support saving and restoring your window configurations.

● Save the user’s data at appropriate times.

● Single-window, library-style apps should implement strategies for saving data at appropriatecheckpoints.

● Multiwindow, document-based apps can use the autosaving and saveless documents capabilities inNSDocument.

● Whenever possible, support sudden termination for your app as well.

Enabling Automatic Termination in Your AppDeclaring support for automatic termination lets the system know that it should manage the actual terminationof your app at appropriate times. An app has two ways to declare its support for automatic termination:

● Include the NSSupportsAutomaticTermination key (with the value YES) in the app’s Info.plistfile. This sets the app’s default support status.

● Use the NSProcessInfo class to declare support for automatic termination dynamically. Use this techniqueto change the default support of an app that includes the NSSupportsAutomaticTermination key inits Info.plist file.

The Core App DesignSupport the Key Runtime Behaviors in Your Apps

2012-01-09 | © 2012 Apple Inc. All Rights Reserved.

36

Page 37: Mos x App Programming Guide

Automatic Data-Saving Strategies Relieve the UserYou should always avoid forcing the user to save changes to their data manually. Instead, implement automaticdata saving. For a multiwindow app based on NSDocument, automatic saving is as simple as overriding theautosavesInPlace class method to returnYES. For more information, seeDocument-BasedAppProgrammingGuide for Mac .

For a single-window, library-style app, identify appropriate points in your code where any user-related changesshould be saved and write those changes to disk automatically. This benefits the user by eliminating the needto think about manually saving changes, and when done regularly, it ensures that the user does not lose muchdata if there is a problem.

Some appropriate times when you can save user data automatically include the following:

● When the user closes the app window or quits the app (applicationWillTerminate:)

● When the app is deactivated (applicationWillResignActive:)

● When the user hides your app (applicationWillHide:)

● Whenever the user makes a valid change to data in your app

The last item means that you have the freedom to save the user’s data at any time it makes sense to do so. Forexample, if the user is editing fields of a data record, you can save each field value as it is changed or you canwait and save all fields when the user displays a new record. Making these types of incremental changes ensuresthat the data is always up-to-date but also requires more fine-grained management of your data model. Insuch an instance, Core Data can help you make the changes more easily. For information about Core Data, seeCore Data Starting Point .

Sudden TerminationSudden termination lets the system know that your app’s process can be killed directly without any additionalinvolvement from your app. The benefit of supporting sudden termination is that it lets the system close appsmore quickly, which is important when the user is shutting down a computer or logging out.

An app has two ways to declare its support for sudden termination:

● Include the NSSupportsSuddenTermination key (with the value YES) in the app’s Info.plist file.

● Use the NSProcessInfo class to declare support for sudden termination dynamically. You can also usethis class to change the default support of an app that includes the NSSupportsSuddenTerminationkey in its Info.plist file.

The Core App DesignSupport the Key Runtime Behaviors in Your Apps

2012-01-09 | © 2012 Apple Inc. All Rights Reserved.

37

Page 38: Mos x App Programming Guide

One solution is to declare global support for the feature globally and then manually override the behavior atappropriate times. Because sudden termination means the system can kill your app at any time after launch,you should disable it while performing actions that might lead to data corruption if interrupted. When theaction is complete, reenable the feature again.

You disable and enable sudden termination programmatically using the disableSuddenTermination andenableSuddenTerminationmethods of theNSProcessInfo class. These methods increment and decrementa counter, respectively, maintained by the process. When the value of this counter is 0, the process is eligiblefor sudden termination. When the value is greater than 0, sudden termination is disabled.

Enabling and disabling sudden termination dynamically also means that your app should save data progressivelyand not rely solely on user actions to save important information. The best way to ensure that your app’sinformation is saved at appropriate times is to support the interfaces in Mac OS X v10.7 for saving your documentand window state. Those interfaces facilitate the automatic saving of relevant user and app data. For moreinformation about saving your user interface state, see “User Interface Preservation” (page 38). For moreinformation about saving your documents, see “Document-Based Apps Are Based on an NSDocumentSubclass” (page 30).

For additional information about enabling and disabling sudden termination, seeNSProcessInfo Class Reference .

User Interface PreservationThe Resume feature of Mac OS X v10.7 saves the state of your app’s windows and restores them duringsubsequent launches of your app. Saving the state of your windows enables you to return your app to thestate it was in when the user last used it. Use the Resume feature especially if your app supports automatictermination, which can cause your app to be terminated while it is running but hidden from the user. If yourapp supports automatic termination but does not preserve its interface, the app launches into its default state.Users who only switched away from your app might think that the app crashed while it was not being used.

Writing Out the State of Your Windows and Custom ObjectsYou must do the following to preserve the state of your user interface:

● For each window, you must set whether the window should be preserved using the setRestorable:method.

● For each preserved window, you must specify an object whose job is to re-create that window at launchtime.

● Any objects involved in your user interface must write out the data they require to restore their state later.

● At launch time, you must use the provided data to restore your objects to their previous state.

The Core App DesignSupport the Key Runtime Behaviors in Your Apps

2012-01-09 | © 2012 Apple Inc. All Rights Reserved.

38

Page 39: Mos x App Programming Guide

The actual process of writing out your application state to disk and restoring it later is handled by Cocoa, butyou must tell Cocoa what to save. Your app’s windows are the starting point for all save operations. Cocoaiterates over all of your app’s windows and saves data for the ones whose isRestorable method returnsYES. Most windows are preserved by default, but you can change the preservation state of a window usingthe setRestorable: method.

In addition to preserving your windows, Cocoa saves data for most of the responder objects associated withthe window. Specifically, it saves the views and window controller objects associated with the window. (For amultiwindow document-based app, the window controller also saves data from its associated documentobject.) Figure 2-8 shows the path that Cocoa takes when determining which objects to save. Window objectsare always the starting point, but other related objects are saved, too.

Figure 2-8 Responder objects targeted by Cocoa for preservation

ViewViewViews

NSWindowController

NSDocument

Archived state

NSWindowNSWindowNSWindow

All Cocoa window and view objects save basic information about their size and location, plus informationabout other attributes that might affect the way they are currently displayed. For example, a tab view savesthe index of the selected tab, and a text view saves the location and range of the current text selection. However,these responder objects do not have any inherent knowledge about your app’s data structures. Therefore, itis your responsibility to save your app’s data and any additional information needed to restore the window toits current state. There are several places where you can write out your custom state information:

● If you subclass NSWindow or NSView, implement the encodeRestorableStateWithCoder: methodin your subclass and use it to write out any relevant data.

The Core App DesignSupport the Key Runtime Behaviors in Your Apps

2012-01-09 | © 2012 Apple Inc. All Rights Reserved.

39

Page 40: Mos x App Programming Guide

Alternatively, your custom responder objects can override the restorableStateKeyPaths method anduse it to specify key paths for any attributes to be preserved. Cocoa uses the key paths to locate and savethe data for the corresponding attribute. Attributes must be compliant with key-value coding and Key-value

observing.

● If your window has a delegate object, implement the window:willEncodeRestorableState:methodfor the delegate and use it to store any relevant data.

● In your window controller, use the encodeRestorableStateWithCoder: method to save any relevantdata or configuration information.

Be judicious when deciding what data to preserve, and strive to write out the smallest amount of informationthat is required to reconfigure your window and associated objects. You are expected to save the actual datathat the window displays and enough information to reattach the window to the same data objects later.

Important Never use the user interface preservation mechanism as a way to save your app’s actual data.The archive created for interface preservation can change frequently and may be ignored altogether if thereis a problem during the restoration process. Your app data should always be saved independently in datafiles that are managed by your app.

For information on how to use coder objects to archive state information, see NSCoder Class Reference . Foradditional information on what you need to do to save state in a multiwindow document-based app, seeDocument-Based App Programming Guide for Mac .

Notifying Cocoa About Changes to Your Interface StateWhenever the preserved state of one of your responder objects changes, mark the object as dirty by calling theinvalidateRestorableState method of that object. Having done so, at some point in the future,encodeRestorableStateWithCoder: message is sent to your responder object. Marking your responderobjects as dirty lets Cocoa know that it needs to write their preservation state to disk at an appropriate time.Invalidating your objects is a lightweight operation in itself because the data is not written to disk right away.Instead, changes are coalesced and written at key times, such as when the user switches to another app orlogs out.

You should mark a responder object as dirty only for changes that are truly interface related. For example, atab view marks itself as dirty when the user selects a different tab. However, you do not need to invalidateyour window or its views for many content-related changes, unless the content changes themselves causedthe window to be associated with a completely different set of data-providing objects.

The Core App DesignSupport the Key Runtime Behaviors in Your Apps

2012-01-09 | © 2012 Apple Inc. All Rights Reserved.

40

Page 41: Mos x App Programming Guide

If you used the restorableStateKeyPaths method to declare the attributes you want to preserve, Cocoapreserves and restores the values of those attributes of your responder object. Therefore, any key paths youprovide should be key-value observing compliant and generate the appropriate notifications. For more informationon how to support key-value observing in your objects, see Key-Value Observing Programming Guide .

Restoring Your Windows and Custom Objects at Launch TImeAs part of your app’s normal launch cycle, Cocoa checks to see whether there is any preserved interface data.If there is, Cocoa uses that data to try to re-create your app’s windows. Every window must identify a restorationclass that knows about the window and can act on its behalf at launch time to create the window when askedto do so by Cocoa.

The restoration class is responsible for creating both the window and all of the critical objects required by thatwindow. For most app styles, the restoration class usually creates one or more controller objects as well. Forexample, in a single-window app, the restoration class would likely create the window controller used tomanage the window and then retrieve the window from that object. Because it creates these controller objectstoo, you typically use high-level application classes for your restoration classes. An app might use the applicationdelegate, a document controller, or even a window controller as a restoration class.

During the launch cycle, Cocoa restores each preserved window as follows:

1. Cocoa retrieves the window’s restoration class from the preserved data and calls itsrestoreWindowWithIdentifier:state:completionHandler: class method.

2. The restoreWindowWithIdentifier:state:completionHandler: class method must call theprovided completion handler with the desired window object. To do this, it does one of the following:

● It creates any relevant controller objects (including the window controller) that might normally becreated to display the window.

● If the controller objects already exist (perhaps because they were already loaded from a nib file), themethod gets the window from those existing objects.

If the window could not be created, perhaps because the associated document was deleted by the user,the restoreWindowWithIdentifier:state:completionHandler: should pass an error object tothe completion handler.

3. Cocoa uses the returned window to restore it and any preserved responder objects to their previous state.

● Standard Cocoa window and view objects are restored to their previous state without additional help.If you subclass NSWindow or NSView, implement the restoreStateWithCoder:method to restoreany custom state.

If you implemented the restorableStateKeyPaths method in your custom responder objects,Cocoa automatically sets the value of the associated attributes to their preserved values. Thus, youdo not have to implement the restoreStateWithCoder: to restore these attributes.

The Core App DesignSupport the Key Runtime Behaviors in Your Apps

2012-01-09 | © 2012 Apple Inc. All Rights Reserved.

41

Page 42: Mos x App Programming Guide

● For the window delegate object, Cocoa calls the window:didDecodeRestorableState: methodto restore the state of that object.

● For your window controller, Cocoa calls the restoreStateWithCoder: method to restore its state.

When re-creating each window, Cocoa passes the window’s unique identifier string to the restoration class.You are responsible for assigning user interface identifier strings to your windows prior to preserving thewindow state. You can assign an identifier in your window’s nib file or by setting your window object'sidentifier property (defined in NSUserInterfaceItemIdentification protocol). For example, youmight give your preferences window an identifier of preferences and then check for that identifier in yourimplementation. Your restoration class can use this identifier to determine which window and associatedobjects it needs to re-create. The contents of an identifier string can be anything you want but should besomething to help you identify the window later.

For a single-window app whose main window controller and window are loaded from the main nib file, thejob of your restoration class is fairly straightforward. Here, you could use the application delegate’s class asthe restoration class and implement the restoreWindowWithIdentifier:state:completionHandler:method similar to the implementation shown in Listing 2-2. Because the app has only one window, it returnsthe main window directly. If you used the application delegate’s class as the restoration class for other windows,your own implementation could use the identifier parameter to determine which window to create.

Listing 2-2 Returning the main window for a single-window app

+ (void)restoreWindowWithIdentifier:(NSString *)identifier

state:(NSCoder *)state

completionHandler:(void (^)(NSWindow *, NSError *))completionHandler

{

// Get the window from the window controller,

// which is stored as an outlet by the delegate.

// Both the app delegate and window controller are

// created when the main nib file is loaded.

MyAppDelegate* appDelegate = (MyAppDelegate*)[[NSApplication sharedApplication] delegate];

NSWindow* mainWindow = [appDelegate.windowController window];

// Pass the window to the provided completion handler.

completionHandler(mainWindow, nil);

}

The Core App DesignSupport the Key Runtime Behaviors in Your Apps

2012-01-09 | © 2012 Apple Inc. All Rights Reserved.

42

Page 43: Mos x App Programming Guide

Apps Are Built Using Many Different PiecesThe objects of the core architecture are important but are not the only objects you need to consider in yourdesign. The core objects manage the high-level behavior of your app, but the objects in your app’s view layerdo most of the work to display your custom content and respond to events. Other objects also play importantroles in creating interesting and engaging apps.

The User InterfaceAn app’s user interface is made up of a menu bar, one or more windows, and one or more views. The menubar is a repository for commands that the user can perform in the app. Commands may apply to the app as awhole, to the currently active window, or to the currently selected object. You are responsible for defining thecommands that your app supports and for providing the event-handling code to respond to them.

You use windows and views to present your app’s visual content on the screen and to manage the immediateinteractions with that content. A window is an instance of the NSWindow class. A panel is an instance of theNSPanel class (which is a descendant of NSWindow) that you use to present secondary content. Single-windowapps have one main window and may have one or more secondary windows or panels. Multiwindow appshave multiple windows for displaying their primary content and may have one or more secondary windowsor panels too. The style of a window determines its appearance on the screen. Figure 2-9 shows the menu bar,along with some standard windows and panels.

Figure 2-9 Windows and menus in an app

Z-order

Menu barDockModal panels Restart alert Font panelApplication windows Untitled Untitled-1 Untitled-2

Levels

The Core App DesignApps Are Built Using Many Different Pieces

2012-01-09 | © 2012 Apple Inc. All Rights Reserved.

43

Page 44: Mos x App Programming Guide

A view, an instance of the NSView class, defines the content for a rectangular region of a window. Views arethe primary mechanism for presenting content and interacting with the user and have several responsibilities.For example:

● Drawing and animation support. Views draw content in their rectangular area. Views that support CoreAnimation layers can use those layers to animate their contents.

● Layout and subview management. Each view manages a list of subviews, allowing you to create arbitraryview hierarchies. Each view defines layout and resizing behaviors to accommodate changes in the windowsize.

● Event handling. Views receive events. Views forward events to other objects when appropriate.

For information about creating and configuring windows, see Window Programming Guide . For informationabout using and creating view hierarchies, see View Programming Guide .

Event HandlingThe system window server is responsible for tracking mouse, keyboard, and other events and delivering themto your app. When the system launches an app, it creates both a process and a single thread for the app. Thisinitial thread becomes the app’s main thread. In it, the NSApplication object sets up the main run loop andconfigures its event-handling code, as shown in Figure 2-10. As the window server delivers events, the appqueues those events and then processes them sequentially in the app’s main run loop. Processing an eventinvolves dispatching the event to the object best suited to handle it. For example, mouse events are usuallydispatched to the view in which the event occurred.

Figure 2-10 Processing events in the main run loop

Operatingsystem

Event queue

Applicationobject

Application

Core objects

The Core App DesignApps Are Built Using Many Different Pieces

2012-01-09 | © 2012 Apple Inc. All Rights Reserved.

44

Page 45: Mos x App Programming Guide

Note A run loop monitors sources of input on a specific thread of execution. The app’s event queuerepresents one of these input sources. While the event queue is empty, the main thread sleeps. Whenan event arrives, the run loop wakes up the thread and dispatches control to the NSApplicationobject to handle the event. After the event has been handled, control passes back to the run loop,which can then process another event, process other input sources, or put the thread back to sleepif there is nothing more to do. For more information about how run loops and input sources work,see Threading Programming Guide .

Distributing and handling events is the job of responder objects, which are instances of the NSResponderclass. The NSApplication, NSWindow, NSDrawer, NSView, NSWindowController, and NSViewControllerclasses are all descendants of NSResponder. After pulling an event from the event queue, the app dispatchesthat event to the window object where it occurred. The window object, in turn, forwards the event to its firstresponder. In the case of mouse events, the first responder is typically the view object (NSView) in which thetouch took place. For example, a mouse event occurring in a button is delivered to the corresponding buttonobject.

If the first responder is unable to handle an event, it forwards the event to its next responder, which is typicallya parent view, view controller, or window. If that object is unable to handle the event, it forwards it to its nextresponder, and so , until the event is handled. This series of linked responder objects is known as the responderchain. Messages continue traveling up the responder chain—toward higher-level responder objects, such asa window controller or the application object—until the event is handled. If the event isn't handled, it isdiscarded.

The responder object that handles an event often sets in motion a series of programmatic actions by the app.For example, a control object (that is, a subclass of NSControl) handles an event by sending an action messageto another object, typically the controller that manages the current set of active views. While processing theaction message, the controller might change the user interface or adjust the position of views in ways thatrequire some of those views to redraw themselves. When this happens, the view and graphics infrastructuretakes over and processes the required redraw events in the most efficient manner possible.

For more information about responders, the responder chain, and handling events, see Cocoa Event-HandlingGuide .

Graphics, Drawing, and PrintingThere are two basic ways in which a Mac OS X app can draw its content:

● Native drawing technologies (such as Core Graphics and AppKit)

● OpenGL

The Core App DesignApps Are Built Using Many Different Pieces

2012-01-09 | © 2012 Apple Inc. All Rights Reserved.

45

Page 46: Mos x App Programming Guide

The native Mac OS X drawing technologies typically use the infrastructure provided by Cocoa views andwindows to render and present custom content. When a view is first shown, the system asks it to draw itscontent. System views draw their contents automatically, but custom views must implement a drawRect:method. Inside this method, you use the native drawing technologies to draw shapes, text, images, gradients,or any other visual content you want. When you want to update your view’s visual content, you mark all orpart of the view invalid by calling its setNeedsDisplay: or setNeedsDisplayInRect:method. The systemthen calls your view’s drawRect: method (at an appropriate time) to accommodate the update. This cyclethen repeats and continues throughout the lifetime of your app.

If you are using OpenGL to draw your app’s content, you still create a window and view to manage your content,but those objects simply provide the rendering surface for an OpenGL drawing context. Once you have thatdrawing context, your app is responsible for initiating drawing updates at appropriate intervals.

For information about how to draw custom content in your views, see Cocoa Drawing Guide .

Text HandlingThe Cocoa text system, the primary text-handling system in Mac OS X, is responsible for the processing anddisplay of all visible text in Cocoa. It provides a complete set of high-quality typographical services throughthe text-related AppKit classes, which enable apps to create, edit, display, and store text with all thecharacteristics of fine typesetting.

The Cocoa text system provides all these basic and advanced text-handling features, and it also satisfiesadditional requirements from the ever-more-interconnected computing world: support for the character setsof all of the world’s living languages, powerful layout capabilities to handle various text directionality andnonrectangular text containers, and sophisticated typesetting capabilities such as control of kerning, ligatures,line breaking, and justification. Cocoa’s object-oriented text system is designed to provide all these capabilitieswithout requiring you to learn about or interact with more of the system than is necessary to meet the needsof your app.

Underlying the Cocoa text system is Core Text, which provides low-level, basic text layout and font-handlingcapabilities to higher-level engines such as Cocoa and WebKit. Core Text provides the implementation formany Cocoa text technologies. App developers typically have no need to use Core Text directly. However, theCore Text API is accessible to developers who must use it directly, such as those writing apps with their ownlayout engine and those porting older ATSUI- or QuickDraw-based codebases to the modern world.

For more information about the Cocoa text system, see Cocoa Text Architecture Guide .

The Core App DesignApps Are Built Using Many Different Pieces

2012-01-09 | © 2012 Apple Inc. All Rights Reserved.

46

Page 47: Mos x App Programming Guide

Implementing the Application Menu BarThe classes NSMenu and NSMenuItem are the basis for all types of menus. An instance of NSMenu manages acollection of menu items and draws them one beneath another. An instance of NSMenuItem represents amenu item; it encapsulates all the information its NSMenu object needs to draw and manage it, but does nodrawing or event-handling itself. You typically use Interface Builder to create and modify any type of menu,so often there is no need to write any code.

The application menu bar stretches across the top of the screen, replacing the menu bar of any other appwhen the app is foremost. All of an app’s menus in the menu bar are owned by one NSMenu instance that’screated by the app when it starts up.

Xcode Templates Provide the Menu BarXcode’s Cocoa application templates provide that NSMenu instance in a nib file called MainMenu.xib. Thisnib file contains an application menu (named with the app’s name), a File menu (with all of its associatedcommands), an Edit menu (with text editing commands and Undo and Redo menu items), and Format, View,Window, and Help menus (with their own menu items representing commands). These menu items, as wellas all of the menu items of the File menu, are connected to the appropriate first-responder action methods.For example, the About menu item is connected to the orderFrontStandardAboutPanel: action methodin the File’s Owner that displays a standard About window.

The template has similar ready-made connections for the Edit, Format, View, Window, and Help menus. If yourapp does not support any of the supplied actions (for example, printing), you should remove the associatedmenu items (or menu) from the nib. Alternatively, you may want to repurpose and rename menu commandsand action methods to suit your own app, taking advantage of the menu mechanism in the template to ensurethat everything is in the right place.

Connect Menu Items to Your Code or Your First ResponderFor your app’s custom menu items that are not already connected to action methods in objects or placeholderobjects in the nib file, there are two common techniques for handling menu commands in a Mac OS X app:

● Connect the corresponding menu item to a first responder method.

● Connect the menu item to a method of your custom application object or your application delegate object.

Of these two techniques, the first is more common given that many menu commands act on the currentdocument or its contents, which are part of the responder chain. The second technique is used primarily tohandle commands that are global to the app, such as displaying preferences or creating a new document. Itis possible for a custom application object or its delegate to dispatch events to documents, but doing so is

The Core App DesignImplementing the Application Menu Bar

2012-01-09 | © 2012 Apple Inc. All Rights Reserved.

47

Page 48: Mos x App Programming Guide

generally more cumbersome and prone to errors. In addition to implementing action methods to respond toyour menu commands, you must also implement the methods of the NSMenuValidation protocol to enablethe menu items for those commands.

Step-by-step instructions for connecting menu items to action methods in your code are given in “Designing

User Interfaces in Xcode”. For more information about menu validation and other menu topics, see ApplicationMenu and Pop-up List Programming Topics .

The Core App DesignImplementing the Application Menu Bar

2012-01-09 | © 2012 Apple Inc. All Rights Reserved.

48

Page 49: Mos x App Programming Guide

iCloud storage is a set of interfaces and services for sharing data among instances of your app running ondifferent devices. The idea behind iCloud is to provide a single place where your app can write its data. Changesmade by one instance of your app are propagated to the user’s other devices seamlessly so that the otherinstances of your app see them too. This creates a more coherent user experience by eliminating the need tosynchronize data explicitly between devices or have a computer act as a hub for storing all of the user’s filesand data.

There are two ways to adopt iCloud storage in your app:

● iCloud document storage—Use this feature to store user documents and app data in the user’s iCloudaccount.

● iCloud key-value data storage—Use this feature to share small amounts of noncritical configuration dataamong instances of your app.

Most of the iCloud interfaces are aimed at helping you manage files, not your user interface. Adopting iCloudstorage requires some changes to your app’s data model and how it tracks and manages files. Depending onyour app, it might also require changes to your app’s user interface and overall configuration. And if you wantto share files between iOS and Mac OS X devices, it might require changing how you construct your file formatstoo.

Access to iCloud is controlled using entitlements, which your app configures through Xcode. If these entitlementsare not present, your app is prevented from accessing files and other data in iCloud. For information abouthow to configure your app’s iCloud entitlements, see “Configuring Your App’s iCloud Entitlements” (page 52).

2012-01-09 | © 2012 Apple Inc. All Rights Reserved.

49

iCloud Storage

Page 50: Mos x App Programming Guide

Important Apps adopting iCloud storage should use automatic reference counting (ARC) for memorymanagement, instead of garbage collection, which doesn't work with iCloud. Manual retain and releaseworks with iCloud, but ARC is preferable because it automates reference counting and is thus easier andmore reliable.

Design Considerations for iCloud AppsWhen adopting iCloud, the first decision you have to make is whether to use document storage or key-valuedata storage. Document storage is intended for storing your app’s data, whether that data is created andmanaged privately by your app or is created by the user and accessible by other means. Document storage isdefinitely intended for apps that work with user-facing data, such as user-created documents, but it is alsouseful for managing the data files your app creates internally too. Key-value storage is intended more fornoncritical configuration data that you want to share among the running instances of your app. For example,you might use key-value storage to store preferences and other bits of configuration data that are secondaryto your app’s behavior. You should avoid using key-value storage to save user-facing data.

iCloud

Key ValueData Storage

DocumentStorage

Doc

Table 3-1 highlights some of the key usage patterns surrounding iCloud storage and how those patterns differfor document storage and key-value storage.

iCloud StorageDesign Considerations for iCloud Apps

2012-01-09 | © 2012 Apple Inc. All Rights Reserved.

50

Page 51: Mos x App Programming Guide

Table 3-1 Differences between document and key-value storage

Key-value storageDocument storageAttribute

Property-list data types only (numbers, strings,dates, and so on)

Files and directoriesWhat kind ofdata can itmanage?

Use key-value storage for things likepreferences and other configuration data thatyou want to share between instances of yourapp but that is not critical to your app’sbehavior. The amount of space in the key-valuestore is limited and the types of data you canstore are limited to property list data types.

Use document storage to manage data that iscritical to your app. You almost always usedocument storage to manage files and datarelated directly to your app’s main data model.Thus, you would use document storage for userdocuments, private app data files, and filescontaining app- or user-generated data.

When wouldyou use it?

No, the data values written to iCloud mostrecently are pushed to all devices sharing thestorage.

YesAre filepresenters andfilecoordinatorsrequired?

Use the default NSUbiquitousKey-ValueStore object to retrieve the value for aknown key.

Use a NSMetadataQuery object to search for files.How do youlocate data?

Set or get keys and values using the defaultNSUbiquitousKeyValueStore object.

Manage files and directores using theNSFileManager class. Open, close, read, andwrite files using standard file system routines.

How do youmanage thedata?

Limited to a maximum of 64 KB (with aseparate per-key limit of 64 KB).

Limited only by the amount of space in the user’siCloud account.

How muchdata can itstore?

The last value set for the key is always thecurrent value. The timestamp provided by thedevice is used to determine the newest value.

Your app’s file presenters must resolve conflictsmanually. For document-based apps, NSDocumentautomatically handles conflicts, presentingversions to the user if necessary.

How areconflictshandled?

com.apple.developer.ubiquity-kvstore-identifiercom.apple.developer.ubiquity-container-identifiersWhatentitlement isrequired touse it?

Keys and values are transferred to and fromiCloud at periodic intervals.

iCloud always uploads file metadata and data froma device when changes occur. Devices downloadfile metadata and changed data at periodicintervals.

When is datasynchronized?

iCloud StorageDesign Considerations for iCloud Apps

2012-01-09 | © 2012 Apple Inc. All Rights Reserved.

51

Page 52: Mos x App Programming Guide

Key-value storageDocument storageAttribute

Call the synchronize method of theNSUbiquitousKeyValueStoreobject. If thatmethod returns YES, iCloud is available andthere are changes to synchronize with yourlocal user defaults database. If that methodreturns NO, iCloud is either not available orthere are no changes to synchronize. Eitherway, use the values in your local user defaultsdatabase.

Call the URLForUbiquity-ContainerIdentifier:method for one of yourregistered container directories. If the methodreturns nil, document storage is not available.

How do youdetect ifiCloud isavailable atlaunch time?

None. In most cases, you should not need toconvey whether key-value data is stored locallyor in iCloud.

None. Your app is responsible for deciding whatinformation (if any) to convey about iCloudsupport. In general, iCloud information should beconveyed seamlessly and involve minimal changesto your user interface.

What userinterfacesupport isprovided?

Configuring Your App’s iCloud EntitlementsApps that use iCloud must be signed with iCloud-specific entitlements. These entitlements provide a level ofsecurity for your app by ensuring that only your apps can access the documents they create. The system alsorelies on the entitlement values you provide to differentiate your app’s documents from other documents inthe user’s iCloud account.

To enable iCloud entitlements for your iOS app in Xcode:

1. Select your app target in Xcode.

2. Select the Summary tab.

3. In the Entitlements section, enable the Enable Entitlements checkbox.

When you enable entitlements for your app target, Xcode automatically configures both the document storageand and key-value data storage entitlements for your app. Each entitlement consists of an entitlement keywhose value is one or more container identifier strings. A container identifier string identifies one of theiCloud container directories you use to store your app’s files. Xcode configures the entitlements in the followingway:

● The iCloud Containers field identifies the list of container directories that your app can access in the user’siCloud storage. (This field corresponds to thecom.apple.developer.ubiquity-container-identifiers entitlement.) The strings you add tothis list must correspond to bundle identifiers for apps created by your team. Xcode uses the current app’s

iCloud StorageConfiguring Your App’s iCloud Entitlements

2012-01-09 | © 2012 Apple Inc. All Rights Reserved.

52

Page 53: Mos x App Programming Guide

bundle identifier to specify the first string; you can change this to a different bundle identifier if you wantmultiple apps to share a main container directory. You can also add additional bundle identifiers for yourteam’s other apps. (The first string must not contain any wildcard characters but subsequent strings mayif you do not want to specify every bundle identifier separately.)

● The iCloud Key-Value Store field contains the single container identifier string corresponding to the iCloudkey-value data storage for your app. (This field corresponds to thecom.apple.developer.ubiquity-kvstore-identifier entitlement.)

The bundle identifiers you specify in Xcode do not represent the fully qualified container identifier strings thatare written to your entitlements file. A fully qualified container identifier is of the form<TEAM_ID>.<BUNDLE_IDENTIFIER> , where<TEAM_ID> is the unique ten-character identifier associated withyour development team and <BUNDLE_IDENTIFIER> is is one of the bundle identifiers in the iCloud Containersfield. When retrieving a URL for a container directory in your code, you need to pass the fully qualified stringto the URLForUbiquityContainerIdentifier: method. However, you can also pass nil to this methodto retrieve the URL for the first container directory in the list.

Note You can find the unique <TEAM_ID> value for your development team in the Member Centeron the Apple Developer website (http://developer.apple.com/membercenter). From the MemberCenter home page, select the Your Account tab and then select Organization Profile from the columnon the left of that tab. Your team’s identifier is in the Company/Organization ID field.

Apps using iCloud document storage can read and write the contents of multiple container directories byspecifying multiple container identifiers in their entitlements file. The iCloud Containers field lets you specifymultiple strings. The first string in this field must always be the main container identifier for your app. Anyadditional strings represent the container identifiers for your other apps. Searches return a merged set of filesfrom all of the available container directories.

For more information about how to configure entitlements for a Mac OS X app, see “Configuring Apps” in ToolsWorkflow Guide for Mac .

iCloud StorageConfiguring Your App’s iCloud Entitlements

2012-01-09 | © 2012 Apple Inc. All Rights Reserved.

53

Page 54: Mos x App Programming Guide

Using iCloud Document StorageiCloud document storage lets you move files and directories to a user’s iCloud account and manage themthere. Changes made to the file or directory on one device are stored locally and then pushed to iCloud usinga local daemon, as shown in Figure 3-1. The transfer of files to and from each device is transparent to yourapp. Thus, apps simply operate on the file as if it is always there.

Figure 3-1 Pushing document changes to iCloud

iCloudDaemon

iCloudDaemon

iCloudDaemon

iCloudDaemon

Local storage Local storage

File

File

File

Designing your app to take advantage of iCloud document storage requires some significant changes. Hereare the main changes needed:

● Early in your app’s execution, call the URLForUbiquityContainerIdentifier: method to determineif iCloud is enabled. If your app is sandboxed, calling this method is also necessary to extend your AppSandbox to include each of your app’s requested container directories ; see “Determining if iCloud DocumentStorage is Available” (page 55).

● Explicitly incorporate file presenters (such as the NSDocument class) into your data layer; see “IncorporatingFile Presenters into Your Workflow” (page 55). Because it handles coordinated file access and versionconflicts for you, using NSDocument is the easiest way to adopt iCloud storage in Mac OS X.

● Explicitly move files to iCloud; see “Manipulating Files and Directories in iCloud” (page 56).

iCloud StorageUsing iCloud Document Storage

2012-01-09 | © 2012 Apple Inc. All Rights Reserved.

54

Page 55: Mos x App Programming Guide

● Be prepared to handle version conflicts for a file; see “Choosing a Strategy to Respond to VersionConflicts” (page 57).

● Make use of searches to locate files in iCloud; see “Incorporating Search into Your Infrastructure” (page58).

● Be prepared to handle cases where files are in iCloud but not fully downloaded to the local device; thismight require providing the user with feedback; see “Determining the Transfer Status of a File orDirectory” (page 59).

● Use Core Data if you want to store live databases in iCloud.

● If you have both iOS and Mac versions of your app, use a common document format for both apps.

Most of the work you do to support iCloud happens in the data layer of your app. Interactions with iCloudoccur mostly through the files and directories that your app uses to store data. But you also need to considerthe implications that the underlying data changes have on your app’s user interface. Wherever possible, theuser should not have to care whether a file is stored locally or in iCloud. The exceptions are in cases where theuser experience might be degraded.

Determining if iCloud Document Storage is AvailableEvery user with an Apple ID receives a free iCloud account but some users might choose not to enable iCloudfor a given device. Early in the execution of your app, before you try to use any other iCloud interfaces, youmust call the URLForUbiquityContainerIdentifier: method to determine if iCloud is enabled. Thismethod returns a valid URL when iCloud is enabled (and the specified container directory is available) or nilwhen iCloud is disabled.

If your app is sandboxed, the first time you call the URLForUbiquityContainerIdentifier: method fora given container directory, Mac OS X extends your App Sandbox to include that container directory. It isimportant that your app call this method at least once to ensure that iCloud is enabled and that your maincontainer directory is accessible. And if your app accesses multiple container directories, you should call themethod once for each directory.

Incorporating File Presenters into Your WorkflowAll files and directories stored in iCloud must be managed by a file presenter object, and all changes you maketo those files and directories must occur through a file coordinator object. A file presenter is an object thatadopts the NSFilePresenter protocol. A file presenter’s job is to act as a responsible agent for a given fileor directory. Before an external source can change a file, the registered file presenters for that file are notifiedand given an opportunity to perform any necessary bookkeeping tasks. When your app wants to change a file,

iCloud StorageUsing iCloud Document Storage

2012-01-09 | © 2012 Apple Inc. All Rights Reserved.

55

Page 56: Mos x App Programming Guide

it must essentially lock the file by making its changes through an NSFileCoordinator object. The filecoordinator prevents external sources from modifying the file at the same time and delivers relevant notificationsto other file presenters.

The simplest way to incorporate file presenters into your app is to use the NSDocument class. This classimplements the methods of the NSFilePresenter protocol and handles all of the file-related managementfor you. All your app has to do is read and write the document data when told to do so. You can use theNSDocument class both for files that contain user-generated content (and thus are displayed directly to theuser) and for files that your app creates on behalf of the user and manages without user intervention.

For more information about how to incorporate the NSDocument class into your app’s data structures, seeDocument-Based App Programming Guide for Mac .

If you're writing a shoebox app, on the other hand, you should not use NSDocument. So if you're doing ashoebox app, you must implement your own file presenter and deal with version conflicts through that API.For information on how to create custom file presenters to manage files and directories, see File SystemProgramming Guide .

Manipulating Files and Directories in iCloudApps use the same technologies to manage files and directories in iCloud that they do for local files anddirectories. Files and directories in iCloud are still just files and directories. You can open them, create them,move them, copy them, read and write from them, delete them, or any of the other operations you might wantto do. The only differences between local files and directories and iCloud files and directories is the URL youuse to access them. URLs for iCloud files and directories are relative to the corresponding iCloud containerdirectory returned by URLForUbiquityContainerIdentifier:.

To move a file or directory to iCloud:

1. Create the file or directory locally. While in use, the file or directory must be managed by a file presenter,such as an NSDocument object.

2. Use the URLForUbiquityContainerIdentifier: method to retrieve a URL for the iCloud containerdirectory in which you want to store the item.

3. Use the container directory URL to build a new URL that specifies the item’s location in iCloud.

4. Call the setUbiquitous:itemAtURL:destinationURL:error:method of NSFileManager to movethe item to iCloud. Never call this method from your app’s main thread; doing so could block your mainthread for an extended period of time or cause a deadlock with one of your app’s own file presenters.

iCloud StorageUsing iCloud Document Storage

2012-01-09 | © 2012 Apple Inc. All Rights Reserved.

56

Page 57: Mos x App Programming Guide

When you move a file or directory to iCloud, the system copies that item into a private local directory so thatit can be monitored by the iCloud daemon. Although a copy of the file remains local to the current device, thefile is also sent to iCloud so that it can be distributed to other devices. The iCloud daemon handles all of thework of making sure that the local copies are the same. So from the perspective of your app, the file just is iniCloud.

All changes you make to a file or directory in iCloud must be made using a file coordinator object. Thesechanges include moving, deleting, copying, or renaming the item. The file coordinator ensures that the iClouddaemon does not change the file or directory at the same time and ensures that other interested parties arenotified of the changes you make.

Note When naming files and directories, use the alphanumeric character set as much as possibleand avoid special punctuation or other special characters. You should also assume that filenamesare case insensitive. Keeping your filenames simple helps ensure that those files can be handledcorrectly on different types of file systems.

For more information about how to manipulate files and directories, see File System Programming Guide .

Choosing a Strategy to Respond to Version ConflictsVersion conflicts for files in iCloud are inevitable, and so your app needs to have a strategy for handling them.Conflicts occur when two instances of an app change a file locally and both changes are then transferred toiCloud. For example, this can happen when the changes are made while a device is not connected to theInternet and cannot transmit changes to iCloud right away. When it does happen, iCloud stores both versionsof the file and notifies the apps’ file presenters that a conflict has occurred and needs to be resolved.

NSDocument Implements Version Conflict Resolution AutomaticallyThe easiest strategy to handle version conflicts is to create a document-based app built around a subclass ofNSDocument, which handles conflict resolution automatically, so you do not need to implement it yourself. Ifa conflict comes in while the document is open, NSDocument presents a sheet asking the user to resolve theconflict (or ignore, which marks them as resolved and accepts the automatic winner of the conflict, usually theone with the most recent modification date). Clicking Resolve invokes the Versions user interface with onlythe conflicting versions visible. The user can choose a particular version and click Restore to make it the winnerof the conflict, or just select Done to accept the automatic winner. Even after the conflict is resolved, NSDocumentalways keeps the conflicting versions, and they can be accessed normally through Versions. For more informationabout using NSDocument, see Document-Based App Programming Guide for Mac .

iCloud StorageUsing iCloud Document Storage

2012-01-09 | © 2012 Apple Inc. All Rights Reserved.

57

Page 58: Mos x App Programming Guide

Your App Can Implement Conflict ResolutionIf your app does not use NSDocument, you must implement conflict resolution yourself. Apps should alwaysattempt to resolve conflict versions as soon as possible. When a conflict occurs, one file is always designatedas the current file and any other versions are marked as conflict versions. Both the current file and any conflictversions are managed by instances of the NSFileVersion class and can be retrieved using class methods ofthat class.

To resolve a conflict:

1. Get the current file version using the currentVersionOfItemAtURL: class method.

2. Get an array of conflict versions using the unresolvedConflictVersionsOfItemAtURL: class method.

3. For each file version object, perform whatever actions are needed to resolve the conflict. For example:

● Merge the changed data from the conflicting files, if it is practical to do so.

● Ignore one of the conflicting versions, if you can do so safely or without losing any data.

● Prompt the user to select which version of the file (current or conflict) to keep. This should always bethe last option.

4. Update the current file as needed:

● If the current file remains the winner, you do not need to update the current file.

● If a conflict version is chosen as the winner, use a coordinated write operation to overwrite the contentsof the current file with the contents of the conflict version.

● If the user chooses to save the conflict version under a different name, create the new file with thecontents of the conflict version.

5. Set the resolved property of the conflict version objects to YES.

Setting this property to YES causes the conflict version objects (and their corresponding files) to be removedfrom the user’s iCloud storage.

For information about responding to conflicts in custom file presenters, see File System Programming Guide .

Incorporating Search into Your InfrastructureUnlike files that live in your app’s local file system, files in iCloud can be added or removed without your appknowing it. When the user creates a new file on one device, that file eventually appears on the user’s otherdevices. If the instance of your app running on those other devices is not actively looking for files, there maybe a delay in them appearing in your user interface. For this reason, apps should use NSMetadataQueryobjects to search for items in iCloud container directories. You can leave a metadata query running in orderto receive notifications as files are added or removed.

iCloud StorageUsing iCloud Document Storage

2012-01-09 | © 2012 Apple Inc. All Rights Reserved.

58

Page 59: Mos x App Programming Guide

Important Metadata queries return results only when iCloud is enabled and the corresponding containerdirectories have been created. At launch time, use the URLForUbiquityContainerIdentifier:methodto determine if iCloud is enabled and your app’s supported container directories are available. That methodalso creates the corresponding directory if it does not yet exist.

Metadata queries search all of the container directories listed in your app’scom.apple.developer.ubiquity-container-identifiers entitlement and return a merged set ofresults. If you want the contents of a single container directory, you can alternatively use theURLForUbiquityContainerIdentifier: method to get the URL for that directory and obtain a static listof its contents using the NSFileManager class.

For information about how to create and configure metadata search queries, see File Metadata SearchProgramming Guide . For information about how to iterate directories using NSFileManager, see File SystemProgramming Guide .

Determining the Transfer Status of a File or DirectoryItems you write to an iCloud container directory are transferred automatically to the iCloud server as quicklyas possible. However, depending on the network and the type of device, a file might not be uploaded to theserver or downloaded to a device immediately. In cases where you need to know the state of a file, you canuse the getResourceValue:forKey:error:method of NSURL to retrieve the value for one of the followingattributes:

NSURLIsUbiquitousItemKey—Indicates whether or not the item is stored in iCloud.

NSURLUbiquitousItemIsDownloadedKey—Indicates whether the current version of the item isdownloaded and accessible.

NSURLUbiquitousItemIsDownloadingKey—Indicates whether the current version of the item is beingdownloaded and is not yet available.

NSURLUbiquitousItemPercentDownloadedKey—For an item being downloaded, indicates whatpercentage of the changes have already been downloaded. You can use this value to update progressbars.

NSURLUbiquitousItemIsUploadedKey—Indicates that locally made changes were successfully uploadedto the iCloud server.

NSURLUbiquitousItemIsUploadingKey—Indicates that locally made changes are being uploaded tothe iCloud server now.

NSURLUbiquitousItemPercentUploadedKey—For an item being uploaded, indicates what percentageof the changes have already been uploaded to the server.

iCloud StorageUsing iCloud Document Storage

2012-01-09 | © 2012 Apple Inc. All Rights Reserved.

59

Page 60: Mos x App Programming Guide

If you try to open a file that is currently being downloaded, Mac OS X blocks the thread that issued the openrequest until the file is downloaded and available for use. Thus, if you are concerned about potential delays,check the file’s current state as needed and possibly update your user interface to reflect that the file is notyet available or is currently downloading.

For more information about the attributes you can request for URLs, see NSURL Class Reference .

Working With Files That Are Not Yet DownloadedWhen a change occurs to a file in iCloud, Mac OS X downloads the file as soon as it can. However, your appcan also call the startDownloadingUbiquitousItemAtURL:error: method to download the changesexplicitly. And you may need to check the status of an upload or download operation, as described in“Determining the Transfer Status of a File or Directory” (page 59).

If your app opens a file that is not yet downloaded, the file coordinator used to open the file blocks your appuntil the file or its changes have been downloaded. Depending on the size of the changes, this might not leadto the best user experience, so it is preferable to check the download status of a file before trying to open it.The NSURL class defines properties related to iCloud items, including whether the file is stored in iCloud andwhether it is currently downloaded. To obtain the value for one of these keys, use thegetResourceValue:forKey:error: method of NSURL. For example, to determine whether a file wasdownloaded, you could use code similar to the following:

- (BOOL)downloadFileIfNotAvailable:(NSURL*)file {

NSNumber* isIniCloud = nil;

if ([file getResourceValue:&isIniCloud forKey:NSURLIsUbiquitousItemKey error:nil]) {

// If the item is in iCloud, see if it is downloaded.

if ([isIniCloud boolValue]) {

NSNumber* isDownloaded = nil;

if ([file getResourceValue:&isDownloaded forKey:NSURLUbiquitousItemIsDownloadedKey error:nil]) {

if ([isDownloaded boolValue])

return YES;

// Download the file.

NSFileManager* fm = [NSFileManager defaultManager];

[fm startDownloadingUbiquitousItemAtURL:file error:nil];

return NO;

iCloud StorageUsing iCloud Document Storage

2012-01-09 | © 2012 Apple Inc. All Rights Reserved.

60

Page 61: Mos x App Programming Guide

}

}

}

// Return YES as long as an explicit download was not started.

return YES;

}

For more information about the iCloud-related properties available for your URLs, see NSURL Class Reference .

Updating Your User Interface for iCloudAny user interface changes you make related to iCloud should be as unobtrusive as possible to the user. Thedocuments you store in iCloud are the same ones you store locally when iCloud is not available. The onlydifference is their location in the file system. So the bulk of your user interface should look about the same.

Sometimes, though, you might want to modify your user interface for iCloud. Modify your UI:

● When a user-generated document must be downloaded before it can be used. Giving the user controlover whether to download a document is needed only if your app presents some sort of document browser.For files your app manages privately, download them automatically if they are not available. Any indicatorsyou use should be subtle and provide the user with the option to begin downloading the document. If adownload might take more than a few seconds, you might also want to display the current downloadprogress.

● When there is a version conflict that the user must resolve. Version conflicts can occur when the samedocument is modified on two different devices at the same time. (This can occur if one of the devices wasnot connected to the network when the changes were made.) If your app needs user assistance to resolvethe conflict, present a subtle indicator that this is the case. Do not display an alert or any sort of disruptiveinterface to notify the user that a conflict exists.

● When you want to give the user the option to enable or disable iCloud usage entirely for your app. Ifyour app includes a Settings bundle or inline preferences, you could include a preference to toggle whetheryour app stores content in iCloud at all. For example, an app whose data consists entirely of privatelymanaged files might do this to give the user the choice of how those files are stored.

For tips and guidance about how to design your app’s user interface, seeMac OS X Human Interface Guidelines .

iCloud StorageUsing iCloud Document Storage

2012-01-09 | © 2012 Apple Inc. All Rights Reserved.

61

Page 62: Mos x App Programming Guide

Using iCloud in Conjunction with Core DataUsing iCloud with a SQLite database is possible only if your app uses Core Data to manage that database.Accessing live database files in iCloud using the SQLite interfaces is not supported and will likely corrupt yourdatabase. However, you can create a Core Data store based on SQLite as long as you follow a few extra stepswhen setting up your Core Data structures. You can also continue to use other types of Core Data stores—thatis, stores not based on SQLite—without any special modifications.

When using Core Data with a SQLite store, the actual database file is never transferred to the iCloud server.Instead, each device maintains its own copy of the SQLite store and synchronizes its contents by writing outchanges to log files. It is the log files that are then transferred to and from iCloud and the other devices. Oneach device, Core Data takes the contents of the log files and uses them to update its local database. The resultis that each local database ends up with the exact same set of changes.

Setting up your Core Data store to handle iCloud requires only a little extra effort on your part. The steps youmust follow depend on whether you are using a single Core Data store as a central library for your app orwhether you are creating separate stores for individual documents.

The following sections assume that you are using a SQLite store to manage your data. SQLite stores are intendedfor apps that have large amounts of data to manage or want fine-grained change notifications. You do notneed to read these sections if you are creating an atomic binary store.

Using Core Data to Manage DocumentsOn Mac OS X, there is no built-in support for document-based apps that want to use Core Data with iCloud,and writing such an app will require a non-trivial amount of work.

For information on how to use Core Data stores to manage the objects in your app, see Core Data ProgrammingGuide .

Using Core Data to Manage a Central LibraryAn app that uses a central Core Data store to manage its data should continue to place that data store in itsApp Sandbox container directory. If the app is not sandboxed, instead use your local file system data storedirectory. Apps with a central data store typically have only one persistent store coordinator object and onepersistent store object. As a result, the simplest solution is to keep the Core Data store locally and use iCloudonly to synchronize changes.

When creating your SQLite store locally, do the following:

iCloud StorageUsing iCloud Document Storage

2012-01-09 | © 2012 Apple Inc. All Rights Reserved.

62

Page 63: Mos x App Programming Guide

1. Include the NSPersistentStoreUbiquitousContentNameKey andNSPersistentStoreUbiquitousContentURLKey keys in the options dictionary you pass to theaddPersistentStoreWithType:configuration:URL:options:error: method when creatingyour data store.

2. Register for the NSPersistentStoreDidImportUbiquitousContentChangesNotificationnotification and use it to update any changed records.

Because you have only one data store, you can use whatever name you want for theNSPersistentStoreUbiquitousContentNameKey key. For theNSPersistentStoreUbiquitousContentURLKey key, the URL you provide should be a directory locatedin one of your iCloud container directories. In other words, the URL should be based on a location returned bythe URLForUbiquityContainerIdentifier:method. Core Data writes changes to the directory you specifyand looks in that directory for changes from other devices. When it detects the changes, it incorporates theminto the local SQLite store and notifies your app.

You should always respond to iCloud-related change notifications. These notifications are a way for you tomake sure your app is using the updated values. If you continue to use an older version of the data, you couldoverwrite the newer data or create a version conflict that would need to be resolved later.

For information on how to create a Core Data store, see Core Data Programming Guide .

Specifying a Custom Location for Core Data Transaction LogsThe transaction logs used to store changes for your app’s Core Data stores are stored in a special directory inthe user’s iCloud account. There is only one directory for all of your app’s Core Data stores. By default, thedirectory name is the same as your app’s bundle identifier and it is located at the top level of your app’s defaultiCloud container directory—that is, the first container directory listed in your entitlements. If your app is alreadyusing that same directory for another purpose, you can change the name of the directory by modifying theoptions of your Core Data stores.

Add the NSPersistentStoreUbiquitousContentURLKey key to the options dictionary you pass to theaddPersistentStoreWithType:configuration:URL:options:error: method when creating yourpersistent store. The value for this key is a URL to the location in one of your iCloud container directories whereyou want to store the transaction logs.

iCloud StorageUsing iCloud Document Storage

2012-01-09 | © 2012 Apple Inc. All Rights Reserved.

63

Page 64: Mos x App Programming Guide

Using iCloud Key-Value Data StorageApps that want to store preferences or small amounts of noncritical configuration data can use the iCloudkey-value data store to do so. The key-value data store is similar conceptually to the local user defaults databasethat you use to store your app’s preferences. The difference is that the keys in the iCloud store are shared byall of the instances of your app running on the user’s other devices. So if one app changes the value of a key,the other apps see that change and can use it to update their configuration.

Important Apps that use the NSUbiquitousKeyValueStore class must request thecom.apple.developer.ubiquity-kvstore-identifier entitlement. If you configure multiple appswith the same value for this entitlement, all of them share the same key-value data. For more informationabout configuring iCloud entitlements, see “Configuring Your App’s iCloud Entitlements” (page 52).

To write data to the key-value data store, use the NSUbiquitousKeyValueStore class. This class is conceptuallysimilar to the NSUserDefaults class in that you use it to save and retrieve simple data types such as numbers,strings, dates, arrays, and so on. The main difference is that the NSUbiquitousKeyValueStore class writesthat data to iCloud instead of to a local file.

The space available in your app’s key-value store is limited to 64 KB. (There is also a per-key limit, which currentlyis set to 64 KB.) Thus, you can use this storage to record small details but should not use it to store userdocuments or other large data archives. Instead, store small pieces of data that might improve the userexperience for your app. For example, a magazine app might store the current issue and page number thatthe user is reading. That way, when the user opens the app on another device, that app can open the magazineto the same issue and page that the user was reading.

The NSUbiquitousKeyValueStore class must not be used as a replacement for the NSUserDefaults class.An app should always write all of its configuration data to disk using the NSUserDefaults class, too. It shouldthen write the data it intends to share to the key-value data store using the NSUbiquitousKeyValueStoreclass. This ensures that if iCloud is not available, you still have access to the configuration data you need.

For more information about how to use the key-value store in your app, see Preferences and SettingsProgramming Guide .

Being a Responsible iCloud AppApps that take advantage of iCloud storage features should act responsibly when storing data there. The spaceavailable in each user’s account is limited and is shared by all apps. Users can see how much space is consumedby a given app and choose to delete documents and data associated with your app. For these reasons, it is inyour app’s interest to be responsible about what files you store. Here are some tips to help you managedocuments appropriately:

iCloud StorageUsing iCloud Key-Value Data Storage

2012-01-09 | © 2012 Apple Inc. All Rights Reserved.

64

Page 65: Mos x App Programming Guide

● Have a good strategy for storing iCloud documents. Whenever possible, give the user a single option tostore all data in iCloud.

● Deleting a document removes it from a user’s iCloud account and from all of that user’s computers anddevices. Make sure that users are aware of this fact and confirm any delete operations. If you want torefresh the local copy of a document, use the evictUbiquitousItemAtURL:error: method ofNSFileManager instead of deleting the file.

● When storing documents in iCloud, place them in the Documents subdirectory whenever possible.Documents inside a Documents directory can be deleted individually by the user to free up space. However,everything outside that directory is treated as data and must be deleted all at once.

● Never store caches or other files that are private to your app in a user’s iCloud storage. A user’s iCloudaccount should be used only for storing user-related data and content that cannot be re-created by yourapp.

● Treat files in iCloud the same way you treat all other files. The time at which to save a file should be drivenby the need of your app and the need to preserve the user’s data. You should not change your app tosave files more or less frequently for iCloud. iCloud automatically optimizes its transfers to the server toensure the best possible performance.

iCloud StorageBeing a Responsible iCloud App

2012-01-09 | © 2012 Apple Inc. All Rights Reserved.

65

Page 66: Mos x App Programming Guide

Enabling a window of your app to assume full-screen mode, taking over the entire screen, provides users witha more immersive, cinematic experience. Full-screen appearance can be striking and can make your app standout. From a practical standpoint, full-screen mode presents a better view of users’ data, enabling them toconcentrate fully on their content without the distractions of other apps or the desktop.

In full-screen mode, by default, the menu bar and Dock are autohidden; that is, they are normally hidden butreappear when the user moves the pointer to the top or bottom of the screen. A full-screen window does notdraw its titlebar and may have special handling for its toolbar.

The full-screen experience makes sense for many apps but not for all. For example, the Finder, Address Book,and Calculator would not provide any benefit to users by assuming full-screen mode. The same is probablytrue for most utility apps. Media-rich apps, on the other hand, can often benefit from full-screen presentation.

Beginning with Mac OS X v10.7, Cocoa includes support for full-screen mode through APIs in NSApplication,NSWindow, and NSWindowDelegate protocol. When the user chooses to enter full-screen mode, Cocoadynamically creates a space and puts the window into that space. This behavior enables the user to have onewindow of an app running in full-screen mode in one space, while using other windows of that app, as wellas other apps, on the desktop in other spaces. While in full-screen mode, the user can switch between windowsin the current app or switch apps.

Apps that have implemented full-screen user interfaces in previous versions of Mac OS X should considerstandardizing on the full-screen APIs in Mac OS X v10.7.

Full-Screen API in NSApplicationFull-screen support in NSApplication is provided by the presentation optionNSApplicationPresentationFullScreen. You can find the current presentation mode via theNSApplication method currentSystemPresentationOptions, which is also key-value observable. Youcan set the presentation options using the NSApplication method setPresentationOptions:. (Be sureto observe the restrictions on presentation option combinations documented withNSApplicationPresentationOptions, and set the presentation options in a try-catch block to ensure thatyour program does not crash from an invalid combination of options.)

2012-01-09 | © 2012 Apple Inc. All Rights Reserved.

66

Implementing the Full-Screen Experience

Page 67: Mos x App Programming Guide

A window delegate may also specify that the window toolbar be removed from the window in full-screenmode and be shown automatically with the menu bar by includingNSApplicationPresentationAutoHideToolbar in the presentation options returned from thewindow:willUseFullScreenPresentationOptions: method of NSWindowDelegate.

Full-Screen API in NSWindowThe app must specify whether a given window can enter full-screen mode. Apps can set collection behaviorusing the setCollectionBehavior: method by passing in various constants, and the current options maybe accessed via the collectionBehavior method. You can choose between two constants to override thewindow collection behavior, as shown in the following table:

BehaviorConstant

The frontmost window with this collection behavior becomesthe full-screen window. A window with this collection behaviorhas a full-screen button in the upper right of its titlebar.

NSWindowCollection-BehaviorFullScreenPrimary

Windows with this collection behavior can be shown in the samespace with the full-screen window.

NSWindowCollection-BehaviorFullScreenAuxiliary

When a window goes into full-screen mode, the styleMask changes to NSFullScreenWindowMask to reflectthe state of the window.The setting of the styleMask goes through the setStyleMask:method. As a result,a window can override this method if it has customization to do when entering or exiting full-screen.

A window can be taken into or out of full-screen mode using the toggleFullScreen: method. If an appsupports full-screen mode, it should add a menu item to the View menu with toggleFullScreen: as theaction, and nil as the target.

Full-Screen API in NSWindowDelegate ProtocolThe following notifications are sent before and after the window enters and exits full-screen mode:

NSWindowWillEnterFullScreenNotification

NSWindowDidEnterFullScreenNotification

NSWindowWillExitFullScreenNotification

NSWindowDidExitFullScreenNotification

Implementing the Full-Screen ExperienceFull-Screen API in NSWindow

2012-01-09 | © 2012 Apple Inc. All Rights Reserved.

67

Page 68: Mos x App Programming Guide

The window delegate has the following corresponding window delegate notification methods:

windowWillEnterFullScreen:

windowDidEnterFullScreen:

windowWillExitFullScreen:

windowDidExitFullScreen:

The NSWindowDelegate protocol methods supporting full-screen mode are listed in Table 4-1.

Table 4-1 Window delegate methods supporting full-screen mode

DescriptionMethod

Invoked to allow the delegateto modify the full-screencontent size.

window: willUseFullScreenContentSize:

Returns the presentationoptions the window will usewhen transitioning to full-screenmode.

window: willUseFullScreenPresentationOptions:

Invoked when the window isabout to enter full-screen mode.The window delegate canimplement this method tocustomize the animation byreturning a custom window orarray of windows containinglayers or other effects.

customWindowsToEnterFullScreenForWindow:

The system has started itsanimation into full-screen mode,including transitioning into anew space. You can implementthis method to perform customanimation with the givenduration to be in sync with thesystem animation.

window:startCustomAnimationToEnterFullScreenWithDuration:

Invoked if the window failed toenter full-screen mode.

windowDidFailToEnterFullScreen:

Implementing the Full-Screen ExperienceFull-Screen API in NSWindowDelegate Protocol

2012-01-09 | © 2012 Apple Inc. All Rights Reserved.

68

Page 69: Mos x App Programming Guide

DescriptionMethod

Invoked when the window isabout to exit full-screen mode.The window delegate canimplement this method tocustomize the animation whenthe window is about to exitfull-screen by returning acustom window or array ofwindows containing layers orother effects.

customWindowsToExitFullScreenForWindow:

The system has started itsanimation out of full-screen,including transitioning back tothe desktop space. You canimplement this method toperform custom animation withthe given duration to be in syncwith the system animation.

window:startCustomAnimationToExitFullScreenWithDuration:

Invoked if the window failed toexit full-screen mode.

windowDidFailToExitFullScreen:

For more information about full-screen mode, see NSWindowDelegate Protocol Reference and the Mac OS XHuman Interface Guidelines .

Implementing the Full-Screen ExperienceFull-Screen API in NSWindowDelegate Protocol

2012-01-09 | © 2012 Apple Inc. All Rights Reserved.

69

Page 70: Mos x App Programming Guide

During the design phase of creating your app, you need to think about how to implement certain featuresthat users expect in well-formed Mac OS X apps. Integrating these features into your app architecture can havean impact on the data model or may require cooperation between significantly different portions in the app.

You Can Prevent the Automatic Relaunch of Your AppBy default, as part of the Resume feature of Mac OS X v10.7, apps that were open at logout are relaunched bythe system when the user logs in again. You can prevent the automatic relaunching of your app at login bysending it a disableRelaunchOnLogin message. This NSApplication method increments a counter thatcontrols the app being relaunched; if the counter is 0 at the time the user logs out, then the app is relaunchedwhen the user logs back in. The counter is initially zero, providing the default relaunch behavior.

Your can reinstate automatic relaunching of your app by sending it an enableRelaunchOnLogin message.This message decrements the relaunch counter, so an equal number of disableRelaunchOnLogin andenableRelaunchOnLogin messages enables relaunching. Both methods are thread safe.

If your app should not be relaunched because it launches via some other mechanism, such as the launchdsystem process, then the recommended practice is to send the app a disableRelaunchOnLogin messageonce, and never pair it with an enableRelaunchOnLogin message.

If your app should not be relaunched because it triggers a restart (for example, if it is an installer), then therecommended practice is to send it a disableRelaunchOnLogin message immediately before you attemptto trigger a restart and send it an enableRelaunchOnLogin message immediately after. This procedurehandles the case where the user cancels restarting; if the user later restarts for another reason, then your appshould be relaunched.

Making Your App Accessible Enables Many UsersMillions of people have a disability or special need. These include visual and hearing impairments, physicaldisabilities, and cognitive and learning challenges. Access to computers is vitally important for this population,because computers can provide a level of independence that is difficult to attain any other way. As populationsaround the world age, an increasing number of people will experience age-related disabilities, such as visionor hearing loss. Current and future generations of the elderly will expect to be able to continue using their

2012-01-09 | © 2012 Apple Inc. All Rights Reserved.

70

Supporting Common App Behaviors

Page 71: Mos x App Programming Guide

computers and accessing their data, regardless of the state of their vision and hearing. Apps that supportcustomizable text displays, access by a screen reader, or the replacement of visual cues by audible ones canserve this population well.

Mac OS X is designed to accommodate assistive technologies and has many built-in features to help peoplewith disabilities. Users access most of this functionality through the Universal Access pane of System Preferences.Some of these built-in technologies take advantage of the same accessibility architecture that allows externalassistive technologies to access your app. Designing your app with accessibility in mind not only allows youto reach a larger group of users, it results in a better experience for all your users.

As a first step in designing your app, be sure to read Mac OS X Human Interface Guidelines . That book providesdetailed specifications and best practices for designing and implementing an intuitive, consistent, andaesthetically pleasing user interface that delivers the superlative experience Macintosh users have come toexpect. During the design process, you also should be aware of the accessibility perspective on many basicdesign considerations. Consider the following basic accessibility-related design principles:

● Support full keyboard navigation. For many users, a mouse is difficult, if not impossible, to use.Consequently, a user should be able to perform all your app’s functions using the keyboard alone.

● Don’t override built-in keyboard shortcuts. This applies both to the keyboard shortcuts Mac OS X reserves(listed in “Keyboard Shortcuts”) and to the accessibility-related keyboard shortcuts (listed in “Accessibility

Keyboard Shortcuts”). As a general rule, you should never override reserved keyboard shortcuts. In particular,you should take care not to override accessibility-related keyboard shortcuts or your app will not beaccessible to users who enable full keyboard access.

A corollary to this principle is to avoid creating too many new keyboard shortcuts that are specific to yourapp. Users should not have to memorize a new set of keyboard commands for each app they use.

● Provide alternatives for drag-and-drop operations. If your app relies on drag-and-drop operations in itsworkflow, you should provide alternate ways to accomplish the same tasks. This may not be easy; in fact,it may require the design of an alternate interface for apps that are heavily dependent on drag and drop.

● Make sure there’s always a way out of your app’s workflow. This is important for all users, of course,but it’s essential for users of assistive technologies. A user relying on an assistive app to use your app mayhave a somewhat narrower view of your app’s user interface. For this reason, it’s especially important tomake canceling operations and retracing steps easy.

In addition to the basic design principles, you should consider the requirements of specific disabilities andresulting design solutions and adaptations you can implement. The main theme of these suggestions is toprovide as many alternate modes of content display as possible, so that users can find the way that suits theirneeds best. Consider the following categories of disabilities:

Supporting Common App BehaviorsMaking Your App Accessible Enables Many Users

2012-01-09 | © 2012 Apple Inc. All Rights Reserved.

71

Page 72: Mos x App Programming Guide

● Visual Disabilities. Visual disabilities include blindness, color blindness, and low vision. Make your appaccessible to assistive apps, such as screen readers. Ensure that color is not the only source of comeparticular information in your user interface. Provide an audio option for all visual cues and feedback, aswell as succinct descriptions of images and animated content.

● Hearing Disabilities. When you design the audio output of your app, remember that some users may notbe able to hear your app’s sound effects well or at all. And, of course, there are situations in which anyuser could not use audio output effectively, such as in a library. Providing redundant audio and visualoutput can aid comprehension for users with other types of disabilities as well, such as cognitive andlearning disabilities.

● Motor and Cognitive Disabilities. People with motor disabilities may need to use alternatives to thestandard mouse and keyboard input devices. Other users may have difficulty with the fine motor controlrequired to double-click a mouse or to press key combinations on the keyboard. Users with cognitive orlearning disabilities may need extra time to complete tasks or respond to alerts.

Mac OS X provides support for many types of disabilities at the system level through solutions offered in theUniversal Access system preferences, illustrated in Figure 5-1. In addition, most standard Cocoa objectsimplement accessibility through the NSAccessibility protocol, providing reasonable default behavior inmost cases, Cocoa apps built with standard objects are automatically accessible. In general, you need toexplicitly implement the NSAccessibility protocol methods only if you subclass one of them, adding newbehavior.

Figure 5-1 Universal Access system preference dialog

Supporting Common App BehaviorsMaking Your App Accessible Enables Many Users

2012-01-09 | © 2012 Apple Inc. All Rights Reserved.

72

Page 73: Mos x App Programming Guide

The NSAccessibility informal protocol defines methods that Cocoa classes must implement to makethemselves available to an external assistive app. An assistive app interacts with your app to allow personswith disabilities to use your app. For example, a person with a visual impairment could use an app to convertmenu items and button labels into speech and then perform actions by verbal command.

An accessible object is described by a set of attributes that define characteristics such as the object type, itsvalue, its size and position on the screen, and its place in the accessibility hierarchy. For some objects, the setof attributes can include parameterized attributes. Parameterized attributes behave similar to a function byallowing you to pass a parameter when requesting an attribute value.

For more information, see Accessibility Overview .

Provide User Preferences for CustomizationPreferences are settings that enable users to customize the appearance or behavior of your software. The MacOS X user defaults system lets you access and manage user preferences. You can use the defaults system toprovide reasonable initial values for app settings, as well as save and retrieve the user's own preference selectionsacross sessions. The Cocoa NSUserDefaults class provides programmatic access to the user defaults system.

The NSUserDefaults class provides convenience methods for accessing common types such as floats, doubles,integers, Booleans, and URLs. A default object must be a property list, that is, an instance of (or for collectionsa combination of instances of ): NSData, NSString, NSNumber, NSDate, NSArray, or NSDictionary. If youwant to store any other type of object, you should typically archive it to create an instance of NSData.

The user defaults system groups defaults into domains. Two of the domains are persistently saved in the userdefaults database: the app domain stores app-specific defaults, and the global domain stores defaults applicableto all apps. In addition, the user defaults system provides three volatile domains whose values last only whilethe user defaults object exists: the argument domain for defaults set from command-line arguments, thelanguages domain containing defaults for a locale if one is specified, and the registration domain for “factorydefaults” registered by the app.

Your app uses the NSUserDefaults class to register default preferences, and typically it also provides a userinterface (a preferences panel) that enables the user to change those preferences. Preferences are stored inthe ~/Library/Preferences/ folder in a standard XML-format property list file as a set of key-value pairs.The app-specific preferences property list is identified by the bundle identifier of the app.

For more details, see Preferences and Settings Programming Guide .

Supporting Common App BehaviorsProvide User Preferences for Customization

2012-01-09 | © 2012 Apple Inc. All Rights Reserved.

73

Page 74: Mos x App Programming Guide

Integrate Your App With Spotlight SearchSpotlight is a fast desktop search technology that allows users to organize and search for files based onmetadata. Metadata is data about a file, rather than the actual content stored in the file. Metadata can includefamiliar information such as an asset’s author and modification date but it can also be keywords or otherinformation that is custom to a particular asset. For example, an image file might have metadata describingthe image’s dimensions and color model.

Developers of apps that save documents to disk should consider providing Spotlight support by implementinga metadata importer. A Spotlight metadata importer is a small plug-in bundle that you create to extractinformation from files created by your app. Spotlight importers are used by the Spotlight server to gatherinformation about new and existing files, as illustrated in Figure 5-2.

Figure 5-2 Spotlight extracting metadata

System Store

SpotlightSpotlight Importers

MDItemkMDItemTitlekMDItemAuthorskMDItemCopyright

...

Spotlight Importers

Apple provides importers for many standard file types that the system uses, including RTF, JPEG, Mail, PDF andMP3. However, if you define a custom document format, you must create a metadata importer for your owncontent. Xcode provides a template for writing Spotlight importer plug-ins. For information about writing aSpotlight importer, see Spotlight Importer Programming Guide .

In addition, you may wish to provide metadata search capability in your app. Cocoa provides theNSMetadataQuery class which enables you to construct queries using a subset of the NSPredicate classesand execute the queries asynchronously. For information about providing Spotlight search capability in yourapp, see File Metadata Search Programming Guide .

For more information about Spotlight, see Spotlight Overview .

Supporting Common App BehaviorsIntegrate Your App With Spotlight Search

2012-01-09 | © 2012 Apple Inc. All Rights Reserved.

74

Page 75: Mos x App Programming Guide

Use Services to Increase Your App’s UsefulnessServices allow a user to access the functionality of one app from within another app. An app that provides aservice advertises the operations it can perform on a particular type of data—for example, encryption of text,optical character recognition of a bitmapped image, or generating text such as a message of the day. Whenthe user is manipulating that particular type of data in some app, the user can choose the appropriate item inthe Services menu to operate on the current data selection (or merely insert new data into the document).

See Services Implementation Guide for more information.

Make Use of Resolution IndependenceResolution independence decouples the resolution of the user's screen from the units you use in your code’sdrawing operations. While Mac OS X v10.4 and earlier assumed a screen resolution of 72 dots per inch (dpi),most modern screens actually have resolutions that are 100 dpi or more. The result of this difference is thatcontent rendered for a 72-dpi screen appears smaller on such screens and will appear smaller yet as screenresolutions increase on future displays.

For apps that depend on a graphical user interface, the dwindling size of user interface elements can makethem too small for users to interact with effectively. For example, a checkbox might be too small to click easily.The solution is to make the drawing sizes specified by the app independent of the display's pixel resolutionand allow arbitrary scaling between the two. Depending on the type of app, the user interface, and the drawingtechnologies used, you may need to update your code to provide the best user experience on aresolution-independent system.

Cocoa apps require little work to support resolution independence because the Cocoa frameworks handle thescaling for you. Standard Cocoa controls, such as buttons and checkboxes, automatically scale correctly.However, depending on how you manipulate windows and the views within them, you may need to makesome changes. In addition, you may need to provide high-resolution versions of any custom artwork.

If you draw directly to the screen on a pixel-by-pixel basis, you need to obtain the current scale factor andscale all your images manually. To obtain the scale factor for a particular window, use theuserSpaceScaleFactor method in the NSWindow class.

In some cases, you may need to convert rectangles or points from the coordinate system of one NSViewinstance to another (typically the superview or subview), or from one NSView instance to the containingwindow. The NSView class defines methods for this purpose and, in Mac OS X v10.5 and later, methods thatshould be used when performing pixel alignment of view content. See Cocoa Drawing Guide and ViewProgramming Guide for more information about coordinate systems.

Supporting Common App BehaviorsUse Services to Increase Your App’s Usefulness

2012-01-09 | © 2012 Apple Inc. All Rights Reserved.

75

Page 76: Mos x App Programming Guide

Make sure your app's custom artwork can scale properly as the pixel density of displays increases. That is, theart needs to be larger in terms of pixel dimensions to avoid loss of resolution at high scale factors onscreen.For example, app icons, custom buttons and other controls, and custom images may need high-resolutionversions of their artwork. If an existing standard control or icon provides the same function as your customversion, you should consider adopting the standard version.

For app icons, you should make sure that the icon family includes images up to 512 x 512 pixels. For new icons,it’s easiest to design the large icons first and then scale them down. You can use the Icon Composer utilityavailable in the /Developer/Applications/Utilities/ folder to create your icons. Icon Composer v2.0and later includes support for larger icon sizes.

For more information about resolution independence, see Resolution Independence Guidelines .

Prepare for Fast User SwitchingFast user switching lets users share a single machine without having to log out every time they want to accesstheir user account. Users share physical access to the machine, including the same keyboard, mouse, andmonitor. However, instead of logging out, a new user simply logs in and switches out the previous user.

Processes in a switched-out login session continue running as before. They can continue processing data,communicating with the system, and drawing to the screen buffer as before. However, because they areswitched out, they do not receive input from the keyboard and mouse. Similarly, if they were to check, themonitor would appear to be in sleep mode. As a result, it may benefit some apps to adjust their behavior whilein a switched-out state to avoid wasting system resources.

While fast user switching is a convenient feature for users, it does provide several challenges for app developers.Apps that rely on exclusive access to certain resources may need to modify their behavior to live in a fast userswitching environment. For example, an app that stores temporary data in /tmp may run into problems whena second instance running under a different user tries to modify the same files in that directory.

To support fast user switching, there are certain guidelines you should follow in developing your apps, mostof which describe safe ways to identify and share system resources. A summary of these guidelines is as follows:

● Incorporate session ID information into the name of any entity that appears in a global namespace,including file names, shared memory regions, semaphores, and named pipes.

Tagging such app-specific resources with a session ID is necessary to distinguish them from similar resourcescreated by apps in a different session. The Security layer of the system assigns a unique ID to each loginsession. Incorporating this ID into cache file or temporary directory names can prevent namespace collisionswhen creating these files. See “Supporting Fast User Switching” for information on how to get the sessionID.

Supporting Common App BehaviorsPrepare for Fast User Switching

2012-01-09 | © 2012 Apple Inc. All Rights Reserved.

76

Page 77: Mos x App Programming Guide

● Don't assume you have exclusive access to any resource, especially TCP/IP ports and hardware devices.

● Don't assume there is only one instance of a per-user service running.

● Use file-level or range-level locks when accessing files.

● Accept and handle user switch notifications. See “User Switch Notifications” for more information.

For more information on user switching, see Multiple User Environments .

Take Advantage of the DockThe Dock is a desktop app designed to reduce desktop clutter, provide users with feedback about an app, andallow users to switch easily between tasks. You can customize your app Dock tile by modifying the Dock iconand adding items to the menu displayed for your app, and you can customize the Dock icon of a minimizedwindow.

An app’s Dock icon is, by default, the app’s icon. While your app is running, you can modify or replace thedefault icon with another image that indicates the current state of your app. For example, the icon for Mailchanges when messages are waiting to be read. A badge—the red circle and number in the figure—is overlaidonto Mail’s app icon to indicate the number of unread messages. The number changes each time Mail retrievesmore messages.

When the user holds the Control key down and clicks on a Dock tile, a menu appears. If your app does nothingto customize the menu, the Dock tile’s menu contains a list of the app’s open documents (if any), followed bythe standard menu items Keep in Dock, Open at Login, Show in Finder, Hide, and Quit. You can add othermenu items to the Dock menu, either statically by providing a custom menu nib file, or dynamically by overridingthe application delegate’s applicationDockMenu: method.

You can also customize a dock tile when your app is not currently running by creating a Dock tile plug-in thatcan update the Dock tile icon and menu. For example, you may want to update the badge text to indicate thatnew content will be available the next time the app is launched, and you may want to customize the app’sDock menu to deal with the new content.

For information explaining how to customize your app’s Dock icon and menu, see Dock Tile ProgrammingGuide .

Supporting Common App BehaviorsTake Advantage of the Dock

2012-01-09 | © 2012 Apple Inc. All Rights Reserved.

77

Page 78: Mos x App Programming Guide

Configuring your app properly is an important part of the development process. Mac OS X apps use a structureddirectory configuration to manage their code and resource files. And although most of the files are customand are there to support your app, some are required by the system or the App Store and must be configuredproperly.

If you intend to sell your application through the Mac App Store or use iCloud storage, you also need to createan explicit app ID, create provisioning profiles, and enable the correct entitlements for your application. Theseprocedures are explained in Tools Workflow Guide for Mac .

All of the requirements for preparing your app and distributing it on the App Store are described in the AppStore Resource Center.

Configuring Your Xcode ProjectTo develop a Mac OS X app, you create an Xcode project. An Xcode Project is a repository for all the files,resources, and information required to build your app (or one of a number of other software products). Aproject contains all the elements used to build your app and maintains the relationships between thoseelements. It contains one or more targets, which specify how to build the software. A project defines defaultbuild settings for all the targets in the project (each target can also specify its own build settings, which overridethe project build settings).

You create a new project using the Xcode File > New > New Project menu command, which invokes the NewProject dialog. This dialog enables you to choose a template for your project, such as a Cocoa app, to name it,and to locate it in your file system. The New Project dialog also provides options, so you can specify whetheryour app uses the Cocoa document architecture or the Core Data framework. When you save your project,Xcode lets you to create a local Git repository to enable source code control for your project.

If you have two or more closely related projects, you should create an Xcode Workspace and add your projectsto it. A workspace groups projects and other documents so you can work on them together. One project canuse the products and shared libraries of another project while building, and Xcode does indexing across theentire workspace, extending the scope of content-aware features such as code completion.

Once you have created your project, you write and edit your code using the Xcode source editor. You also useXcode to build and debug your code, setting breakpoints, viewing the values of variables, stepping throughrunning code, and reviewing issues found during builds or code analysis.

2012-01-09 | © 2012 Apple Inc. All Rights Reserved.

78

Build-Time Configuration Details

Page 79: Mos x App Programming Guide

When you create a new project, it includes one or more targets, where each target specifies one build productand the instructions for how the product is to be built. Most developers never need to change the default ofthe vast majority of build settings, but there are a few basic settings that you should check for each target,such as the deployment target (platform, OS version, and architecture), main user interface, and linkedframeworks and libraries.

You also need to set up one or more schemes to specify the targets, build configuration, and executableconfiguration to use when the product specified by the target is launched. You use the project editor and thescheme editing dialog to edit build settings and control what happens when you build and run your code.“Building and Running Your Code” explains how to work with Xcode build settings and schemes.

For more information about using Xcode to create, configure, build, and debug your project, as well as archivingyour program to package it for distribution or submission to the Mac App Store, see Xcode 4 User Guide .

The Information Property List FileAn information property list (Info.plist) file contains essential runtime-configuration information for the app.Xcode provides a version of this file with every Mac OS X application project and configures it with severalstandard keys. Although the default keys cover several important aspects of the app’s configuration, most appsrequire additional keys to specify their configuration fully.

Build-Time Configuration DetailsThe Information Property List File

2012-01-09 | © 2012 Apple Inc. All Rights Reserved.

79

Page 80: Mos x App Programming Guide

To view the contents of your Info.plist file, select it in the Groups & Files pane. Xcode displays a propertylist editor similar to the one in Figure 6-1 (which is from Xcode 3.2.5). You can use this window to edit theproperty values and add new key-value pairs. By default, Xcode displays a more user-friendly version of eachkey name. To see the key names that Xcode adds to the Info.plist file, Control-click an item in the editorand choose Show Raw Keys/Values from the contextual menu that appears.

Figure 6-1 The information property list editor

Xcode automatically adds some important keys to the Info.plist file of all new projects and sets their initialvalues. However, there are several keys that Mac OS X apps use commonly to configure their launch environmentand runtime behavior. Here are some keys that you might want to add to your app’s Info.plist file specificallyfor Mac OS X:

● LSApplicationCategoryType (required for apps distributed using the App Store)

● CFBundleDisplayName

● LSHasLocalizedDisplayName

● NSHumanReadableCopyright

● LSMinimumSystemVersion

● UTExportedTypeDeclarations

● UTImportedTypeDeclarations

Build-Time Configuration DetailsThe Information Property List File

2012-01-09 | © 2012 Apple Inc. All Rights Reserved.

80

Page 81: Mos x App Programming Guide

For detailed information about these and other keys that you can include in your app’s Info.plist file, seeInformation Property List Key Reference .

The Mac OS X Application BundleWhen you build your Mac OS X app, Xcode packages it as a bundle. A bundle is a directory in the file systemthat groups related resources together in one place. A Mac OS X application bundle contains a single Contentsdirectory, inside of which are additional files and directories with the app’s code, resources, and localizedcontent. Table 6-1 lists the contents of a typical Mac OS X application bundle, which for demonstration purposesis called MyApp. This example is for illustrative purposes only. Some of the files listed in this table may notappear in your own application bundles.

Table 6-1 A typical application bundle

DescriptionFiles

The executable file containing yourapp’s code. The name of this file is thesame as your app name minus the.app extension.

This file is required.

Contents/MacOS/MyApp

Also known as the information propertylist file, a file containing configurationdata for the app. The system uses thisdata to determine how to interact withthe app at specific times.

This file is required. For moreinformation, see “The InformationProperty List File” (page 79).

Contents/Info.plist

Build-Time Configuration DetailsThe Mac OS X Application Bundle

2012-01-09 | © 2012 Apple Inc. All Rights Reserved.

81

Page 82: Mos x App Programming Guide

DescriptionFiles

The English version of the app’s mainnib file. This file contains the defaultinterface objects to load at app launchtime. Typically, this nib file contains theapp’s menu bar and applicationdelegate object. It may also containother controller objects that shouldalways be available at launch time.(The name of the main nib file can bechanged by assigning a different valueto the NSMainNibFile key in theInfo.plist file.)

This file is optional but recommended.For more information, see “TheInformation Property List File” (page79)

Contents/Resources/English.lproj/MainMenu.nib

Nonlocalized resources are placed atthe top level of the Resourcesdirectory (sun.png represents anonlocalized image file in theexample). The app uses nonlocalizedresources when no localized version ofthe same resource is provided. Thus,you can use these files in situationswhere the resource is the same for alllocalizations.

Contents/Resources/sun.png (or other resource files)

Build-Time Configuration DetailsThe Mac OS X Application Bundle

2012-01-09 | © 2012 Apple Inc. All Rights Reserved.

82

Page 83: Mos x App Programming Guide

DescriptionFiles

Localized resources are placed insubdirectories with an ISO 639-1language abbreviation for a name plusan .lproj suffix. Although more humanreadable names (such as English.lproj,French.lproj, and German.lproj) can beused for directory names, the ISO 639-1names are preferred because theyallow you to include an ISO 3166-1regional designation. (For example, theen_GB.lproj directory containsresources localized for English asspoken in Great Britain, the es.lprojdirectory contains resources localizedfor Spanish, and the de.lproj directorycontains resources localized forGerman.)

Contents/Resources/en_GB.lproj

Contents/Resources/es.lproj

Contents/Resources/de.lproj

Other language-specific project directories

A Mac OS X app should be internationalized and have a language.lproj directory for each language it supports.Even if you provide localized versions of your resources, though, include a default version of these files at thetop level of your Resources directory. The default version is used when a specific localization is not available.

At runtime, you can access your app’s resource files from your code using the following steps:

1. Obtain a reference to your app’s main bundle object (typically using theNSBundle class).

2. Use the methods of the bundle object to obtain a file-system path to the desired resource file.

3. Open (or access) the file and use it.

You obtain a reference to your app’s main bundle using the mainBundle class method of NSBundle. ThepathForResource:ofType: method is one of several NSBundle methods that you can use to retrieve thelocation of resources. The following example shows how to locate a file called sun.png and create an imageobject using it. The first line gets the bundle object and the path to the file. The second line creates an NSImageobject that you could use to display the image in your app.

NSString* imagePath = [[NSBundle mainBundle] pathForResource:@"sun" ofType:@"png"];

NSImage* sunImage = [[NSImage alloc] initWithContentsOfFile:imagePath];

Build-Time Configuration DetailsThe Mac OS X Application Bundle

2012-01-09 | © 2012 Apple Inc. All Rights Reserved.

83

Page 84: Mos x App Programming Guide

Note If you prefer to use Core Foundation to access bundles, you can obtain a CFBundleRef opaquetype using the CFBundleGetMainBundle function. You can then use that opaque type plus theCore Foundation functions to locate any bundle resources.

For information on how to access and use resources in your app, see Resource Programming Guide . For moreinformation about the structure of a Mac OS X application bundle, see Bundle Programming Guide .

Internationalizing Your AppThe process of preparing a project to handle content in different languages is called internationalization. Theprocess of converting text, images, and other content into other languages is called localization. Projectresources that are candidates for localization include:

● Code-generated text, including locale-specific aspects of date, time, and number formatting

● Static text—for example, strings you specify programmatically and display in parts of your user interfaceor an HTML file containing app help

● Icons (including your app icon) and other images when those images either contain text or have someculture-specific meaning

● Sound files containing spoken language

● Nib files

Build-Time Configuration DetailsInternationalizing Your App

2012-01-09 | © 2012 Apple Inc. All Rights Reserved.

84

Page 85: Mos x App Programming Guide

Users select their preferred language from the Language and Text system preference, shown in Figure 6-2.

Figure 6-2 The Language preference view

Your application bundle can include multiple language-specific resource directories. The names of thesedirectories consist of three components: an ISO 639-1 language code, an optional ISO 3166-1 region code, anda .lproj suffix. For example, to designate resources localized to English, the bundle would be named en.lproj.By convention, these directories are called lproj directories.

Note You may use ISO 639-2 language codes instead of those defined by ISO 639-1. For moreinformation about language and region codes, see “Language and Locale Designations” inInternationalization Programming Topics .

Each lproj directory contains a localized copy of the app’s resource files. When you request the path to aresource file using the NSBundle class or the CFBundleRef opaque type, the path you get back automaticallyreflects the resource for the user’s preferred language.

For more information about internationalization and how you support localized content in your Mac OS Xapps, see Internationalization Programming Topics .

Build-Time Configuration DetailsInternationalizing Your App

2012-01-09 | © 2012 Apple Inc. All Rights Reserved.

85

Page 86: Mos x App Programming Guide

As you develop your app and your project code stabilizes, you can begin performance tuning. Of course, youwant your app to launch and respond to the user’s commands as quickly as possible. A responsive app fitseasily into the user’s workflow and feels well crafted.

Speed Up Your App’s Launch TimeYou can improve your app’s performance at launch time by minimizing or deferring work until after the launchsequence has completed. The launch of an app provides users with the first impression of your app, and it’ssomething they see on a regular basis.

Your overriding goal during launch should be to display the app’s menu bar and main window and then startresponding to user commands as quickly as possible. Making your app responsive to commands quicklyprovides a better experience for the user. The following sections provide some general tips on how to makeyour app launch faster.

Delay Initialization CodeMany apps spend a lot of time initializing code that isn’t used until much later. Delaying the initialization ofsubsystems that are not immediately needed can speed up your launch time considerably. Remember thatthe goal is to display your app interface quickly, so try to initialize only the subsystems related to that goalinitially.

Once you have posted your interface, your app can continue to initialize additional subsystems as needed.However, remember that just because your app is able to process commands does not mean you need all ofthat code right away. The preferred way of initializing subsystems is on an as-needed basis. Wait until the userexecutes a command that requires a particular subsystem and then initialize it. That way, if the user neverexecutes the command, you will not have wasted any time running the code to prepare for it.

Avoid putting a lot of extraneous initialization code in your awakeFromNib methods. The system calls theawakeFromNib method of your main nib file before your app enters its main event loop. Use that method toinitialize the objects in that nib and to prepare your app interface. For all other initialization, use theapplicationDidFinishLaunching: method of your NSApplicationDelegate object instead. For moreinformation on nib files and how they are loaded, see Resource Programming Guide .

2012-01-09 | © 2012 Apple Inc. All Rights Reserved.

86

Tuning for Performance and Responsiveness

Page 87: Mos x App Programming Guide

Simplify Your Main Nib FileLoading a nib file is an expensive process that can slow down your app launch time if you are not careful.When a nib file is loaded, all of the objects in that file are instantiated and made ready for use. The more objectsyou include in your app’s main nib, the more time it takes to load that file and launch your app.

The instantiation process for objects in a nib file requires that any frameworks used by those objects mustthemselves reside in memory. Thus loading a nib for a Cocoa app would likely require the loading of both theAppKit and Foundation frameworks, if they were not already resident in memory. Similarly, if you declare acustom class in your main nib file and that class relies on other frameworks, the system must load thoseframeworks as well.

When designing your app’s main nib file, you should include only those objects needed to display your app’sinitial user interface. Usually, this would involve just your app’s menu bar and initial window. For any customclasses you include in the nib, make sure their initialization code is as minimal as possible. Defer anytime-consuming operations or memory allocations until after the class is instantiated.

Minimize Global VariablesFor both apps and frameworks, be careful not to declare global variables that require significant amounts ofinitialization. The system initializes global variables before calling your app’s main routine. If you use a globalvariable to declare an object, the system must call the constructor or initialization method for that object duringlaunch time. In general, it’s best to avoid declaring objects as global variables altogether when you can use apointer instead.

If you are implementing a framework or any type of reusable code module, you should also minimize thenumber of global variables you declare. Each app that links to a framework acquires a copy of that framework’sglobal variables. These variables might require several pages of virtual memory, which then increases thememory footprint of the app. An increased memory footprint can lead to paging in the app, which has atremendous impact on performance.

One way to minimize the global variables in a framework is to store the variables in a malloc-allocated blockof memory instead. In this technique, you access the variables through a pointer to the memory, which youstore as a global variable. Another advantage of this technique is that it allows you to defer the creation of anyglobal variables until the first time they are actually used. See “Tips for Allocating Memory” in Memory UsagePerformance Guidelines for more information.

Tuning for Performance and ResponsivenessSpeed Up Your App’s Launch Time

2012-01-09 | © 2012 Apple Inc. All Rights Reserved.

87

Page 88: Mos x App Programming Guide

Minimize File Access at Launch TimeAccessing a file is one of the slowest operations performed on a computer, so it is important that you do it aslittle as possible, especially at launch time. There is always some file access that must occur at launch time,such as loading your executable code and reading in your main nib file, but reducing your initial dependenceon startup files can provide significant speed improvements.

If you can delay the reading of a file until after launch time, do so. The following list includes some files whosecontents you may not need until after launch:

● Frameworks not used directly by your app—Avoid calling code that uses nonessential frameworks untilafter launch.

● Nib files whose contents are not displayed immediately—Make sure your nib files and awakeFromNib:

code are not doing too much at launch time. See “Simplify Your Main Nib File” (page 87) for moreinformation.

● User preference files—User preferences may not be local so read them later if you can.

● Font files—Consider delaying font initialization until after the app has launched.

● Network files—Avoid reading files located on the network if at all possible.

If you must read a file at launch time, do so only once. If you need multiple pieces of data from the same file,such as from a preferences file, consider reading all of the data once rather than accessing the file multipletimes.

Don’t Block the Main ThreadThe main thread is where your app handles user events and other input, so you should keep it free as muchas possible to be responsive to the user. In particular, never use the main thread to perform long-running orpotentially unbounded tasks, such as tasks that require network access. Instead, always move those tasks ontobackground threads. The preferred way to do so is to use Grand Central Dispatch (GCD) or operation objectsto perform tasks asynchronously.

For more information about doing work on background threads, see Concurrency Programming Guide .

Decrease Your App’s Code SizeIn the context of performance, the more memory your app occupies, the more inefficient it is. More memorymeans more memory allocations, more code, and a greater potential for paging.

Tuning for Performance and ResponsivenessDon’t Block the Main Thread

2012-01-09 | © 2012 Apple Inc. All Rights Reserved.

88

Page 89: Mos x App Programming Guide

Reducing your code footprint is not just a matter of turning on code optimizations in your compiler, althoughthat does help. You can also reduce your code footprint by organizing your code so that only the minimumset of required functions is in memory at any given time. You implement this optimization by profiling yourcode.

See “Memory Instruments” in Instruments User Guide for information about profiling your app’s memoryallocations.

Compiler-Level OptimizationsThe Xcode compiler supports optimization options that let you choose whether you prefer a smaller binarysize, faster code, or faster build times. For new projects, Xcode automatically disables optimizations for thedebug build configuration and selects the Fastest, Smallest option for the release build configuration. Codeoptimizations of any kind result in slower build times because of the extra work involved in the optimizationprocess. If your code is changing, as it does during the development cycle, you do not want optimizationsenabled. As you near the end of your development cycle, though, the release build configuration can give youan indication of the size of your finished product, so the Fastest, Smallest option is appropriate.

Table 7-1 lists the optimization levels available in Xcode. When you select one of these options, Xcode passesthe appropriate flags to the compiler for the given group or files. These options are available at the target levelor as part of a build configuration. See the Xcode Build System Guide for information on working with buildsettings for your project.

Table 7-1 Compiler optimization options

DescriptionXcode setting

The compiler does not attempt to optimize code. Use this option during developmentwhen you are focused on solving logic errors and need a fast compile time. Do notuse this option for shipping your executable.

None

The compiler performs simple optimizations to boost code performance whileminimizing the impact to compile time. This option also uses more memory duringcompilation.

Fast

The compiler performs nearly all supported optimizations that do not require aspace-time tradeoff. The compiler does not perform loop unrolling or function inliningwith this option. This option increases both compilation time and the performanceof generated code.

Faster

The compiler performs all optimizations in an attempt to improve the speed of thegenerated code. This option can increase the size of generated code as the compilerperforms aggressive inlining of functions.

This option is generally not recommended.

Fastest

Tuning for Performance and ResponsivenessDecrease Your App’s Code Size

2012-01-09 | © 2012 Apple Inc. All Rights Reserved.

89

Page 90: Mos x App Programming Guide

DescriptionXcode setting

The compiler performs all optimizations that do not typically increase code size. Thisis the preferred option for shipping code because it gives your executable a smallermemory footprint.

Fastest,Smallest

As with any performance enhancement, do not make assumptions about which option will give you the bestresults. You should always measure the results of each optimization you try. For example, the Fastest optionmight generate extremely fast code for a particular module, but it usually does so at the expense of executablesize. Any speed advantages you gain from the code generation are easily lost if the code needs to be pagedin from disk at runtime.

Use Core Data for Large Data SetsIf your app manipulates large amounts of structured data, store it in a Core Data persistent store or in a SQLitedatabase instead of in a flat file. Both Core Data and SQLite provide efficient ways to manage large data setswithout requiring the entire set to be in memory all at once. Use SQLite if you deal with low-level data structures,or an existing SQLite database. Core Data provides a high-level abstraction for efficient object-graphmanagement with an Objective-C interface; it is, however, an advanced framework and you shouldn't use ituntil you have gained adequate experience.

For more information about Core Data, see Core Data Programming Guide and Optimizing Core Data withInstruments .

Eliminate Memory LeaksYour app should not have any memory leaks. You can use the Instruments app to track down leaks in yourcode, both in the simulator and on actual devices. See “Memory Instruments” in Instruments User Guide forinformation about finding memory leaks.

Dead Strip Your CodeFor statically linked executables, dead-code stripping is the process of removing unreferenced code from theexecutable file. If the code is unreferenced, it must not be used and therefore is not needed in the executablefile. Removing dead code reduces the size of your executable and can help reduce paging.

To enable dead-code stripping in Xcode, in the Linking group of Build Settings, set the Dead Code Strippingoption to Yes.

Tuning for Performance and ResponsivenessDecrease Your App’s Code Size

2012-01-09 | © 2012 Apple Inc. All Rights Reserved.

90

Page 91: Mos x App Programming Guide

Strip Symbol InformationDebugging symbols and dynamic-binding information can take up a lot of space and comprise a largepercentage of your executable’s size. Before shipping your code, you should strip out all unneeded symbols.

To strip debugging symbols from your executable, change the Xcode compiler code generation GenerateDebug Symbols option to No. You can also generate debugging symbols on a target-by-target basis if youprefer. See the Xcode Help for more information on build configurations and target settings.

Tuning for Performance and ResponsivenessDecrease Your App’s Code Size

2012-01-09 | © 2012 Apple Inc. All Rights Reserved.

91

Page 92: Mos x App Programming Guide

This table describes the changes to Mac App Programming Guide .

NotesDate

Summarized chapter on document-based apps, added iCloud chapter,and revised sandbox information. Made minor technical and editorialrevisions throughout. Changed title from Mac OS X ApplicationProgramming Guide.

2012-01-09

New document describing the development process for Mac OS Xapplications.

2011-06-27

2012-01-09 | © 2012 Apple Inc. All Rights Reserved.

92

Document Revision History

Page 93: Mos x App Programming Guide

Apple Inc.© 2012 Apple Inc.All rights reserved.

No part of this publication may be reproduced,stored in a retrieval system, or transmitted, in anyform or by any means, mechanical, electronic,photocopying, recording, or otherwise, withoutprior written permission of Apple Inc., with thefollowing exceptions: Any person is herebyauthorized to store documentation on a singlecomputer for personal use only and to printcopies of documentation for personal useprovided that the documentation containsApple’s copyright notice.

The Apple logo is a trademark of Apple Inc.

No licenses, express or implied, are granted withrespect to any of the technology described in thisdocument. Apple retains all intellectual propertyrights associated with the technology describedin this document. This document is intended toassist application developers to developapplications only for Apple-labeled computers.

Apple Inc.1 Infinite LoopCupertino, CA 95014408-996-1010

.Mac is a registered service mark of Apple Inc.

App Store is a service mark of Apple Inc.

iCloud is a registered service mark of Apple Inc.

Mac App Store is a service mark of Apple Inc.

Apple, the Apple logo, Bonjour, Cocoa, eMac,Finder, Instruments, iPhoto, iTunes, Keychain,Mac, Mac OS, Macintosh, Objective-C, QuickDraw,Sand, Spotlight, Time Machine, and Xcode aretrademarks of Apple Inc., registered in the UnitedStates and other countries.

IOS is a trademark or registered trademark ofCisco in the U.S. and other countries and is usedunder license.

OpenGL is a registered trademark of SiliconGraphics, Inc.

UNIX is a registered trademark of The Open Group

Even though Apple has reviewed this document,APPLE MAKES NO WARRANTY OR REPRESENTATION,EITHER EXPRESS OR IMPLIED, WITH RESPECT TO THISDOCUMENT, ITS QUALITY, ACCURACY,MERCHANTABILITY, OR FITNESS FOR A PARTICULARPURPOSE. AS A RESULT, THIS DOCUMENT IS PROVIDED“AS IS,” AND YOU, THE READER, ARE ASSUMING THEENTIRE RISK AS TO ITS QUALITY AND ACCURACY.

IN NO EVENT WILL APPLE BE LIABLE FOR DIRECT,INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIALDAMAGES RESULTING FROM ANY DEFECT ORINACCURACY IN THIS DOCUMENT, even if advised ofthe possibility of such damages.

THE WARRANTY AND REMEDIES SET FORTH ABOVEARE EXCLUSIVE AND IN LIEU OF ALL OTHERS, ORALOR WRITTEN, EXPRESS OR IMPLIED. No Apple dealer,agent, or employee is authorized to make anymodification, extension, or addition to this warranty.

Some states do not allow the exclusion or limitationof implied warranties or liability for incidental orconsequential damages, so the above limitation or

exclusion may not apply to you. This warranty givesyou specific legal rights, and you may also have otherrights which vary from state to state.