Documentation Archive Developer
Search

Meet User Expectations

OS X incorporates the latest technologies for creating great apps. But what makes your app great is not the sophisticated technologies it uses but how well the app helps its users accomplish their goals. Users will ignore an app that gets in their way but will keep using one that makes working with it (or playing with it) an enjoyable and productive experience. This article introduces the common features of a great OS X app and the key technologies of OS X that help you to create great apps.

Design Your App for Ease of Use

As you design your app, you want to think about the tasks that your users will perform with it and then find ways to make those tasks easier to accomplish. The best apps have certain features that are based on time-tested design principles. Some of these features use technologies that were recently added to the operating system. For example, great OS X apps:

  • Save user data without user interaction. Users should not have to save their work manually. If you base your app on the document model, Cocoa does much of this work for you.

  • Restore users’ work environment at login. Cocoa helps you archive the current state of your app’s interface (including the state of unsaved documents) and restores that state at launch time.

  • Terminate automatically. A user should never have to quit your app explicitly. The automatic termination feature moves an app to the background (so it appears to have been quit) when the user closes the app’s windows. Subsequent launches are nearly instantaneous because the app simply moves back to the foreground. When there is memory pressure, the system may kill an app’s process even though the app is running.

  • Save your documents in iCloud. If you enable iCloud in your app, when users create and edit documents all their changes are automatically pushed to all their devices—Mac, iPhone, iPad, or iPod touch—on which your app is installed. The document architecture of the AppKit framework helps you to do this.

  • Make your app accessible. Your app should have an intuitive interface that enables users with disabilities to accomplish tasks quickly and efficiently. The frameworks provide support for assistive applications.

  • Respond to trackpad gestures. Gestures in your app provide shortcuts for common tasks and can supplement existing controls and menu commands. OS X supports gestures through the normal event-handling mechanism.

  • Offer a full-screen version of the app. A full-screen experience eliminates outside distractions and allows users to focus on an app’s content

  • Let users view documents from outside the app. If your app supports custom documents, offer this extra benefit to users by using a Quick Look plug-in.

  • Support user-friendly features. Users of an app should always be in control, receive consistent feedback, and be encouraged to explore. Thus an app should implement direct manipulation, drag-and-drop, and reversible actions (undo).

For your app you might consider minimizing or eliminating the user’s direct interactions with the file system. Some apps, sometimes called “shoebox” apps, give users a great experience by presenting documents or other user data in a simplified browser. iPhoto is an example of such an app. It lets users deal with thumbnail images of their photos rather than the cryptic file names generated by cameras.

Because Cocoa supports all of the preceding features, you can incorporate them with relatively little effort. You can find more information about many of these tasks and design principles in Mac App Programming Guide.

Take Advantage of a Sophisticated Graphics Environment

High-quality graphics and animation make your app look great and can convey a lot of information to the user. Animations are a great way to give feedback about changes to your user interface; for example, the “genie effect” shows where minimized windows go. Both the AppKit and Core Animation frameworks have facilities for quickly creating sophisticated animations. Also include high-resolution versions of your art and graphics. OS X automatically loads high-resolution image resources when an app runs on a screen whose scaling factor is greater than 1.0. Including such image resources makes your app’s graphics look even sharper and crisper on screens with higher pixel counts.

OS X Technology Overview contains information about the graphics technologies available in OS X.

Take Advantage of the Runtime Environment

When you are ready to begin writing actual code, OS X gives you a lot of technologies that make your job as an app developer easier. Your app gets some of these features for free, with no coding required; for others, you need to write code. The following discussion covers several of the latter technologies.

Concurrency and Threading

Each process in OS X starts off with a single thread of execution—the main thread—but it can create more threads as needed. You create secondary threads to perform work concurrently and asynchronously on them, thereby improving overall application performance. For most types of work, the best way to create threads (indirectly) is to use Grand Central Dispatch (GCD) or operation objects, a Cocoa concurrency technology implemented by the NSOperation class.

GCD and operation objects simplify or eliminate many of the problems normally associated with threaded programming, such as synchronization and locking. They define an asynchronous programming model in which you specify only the work to be performed and the order in which you want it performed. The system handles the tedious work required to schedule the necessary threads and execute your tasks as efficiently as possible on the current hardware.

Concurrency Programming Guide describes how to use GCD and operation objects to implement concurrency in your apps.

The File System

OS X structures the file system to give users a great experience. For example, rather than exposing the entire file system to the user, the Finder and the system’s open and save panels hide any files and directories that a typical user should not need to use, such as the contents of low-level UNIX directories. Hiding unneeded directories results in a simpler interface for end users. Apps can still access any files and directories for which they have valid permissions, regardless of whether they are hidden by the Finder.

The HFS+ file system of OS X is case insensitive but also case preserving. Therefore, when specifying filenames and directories in your code, always assume case sensitivity. Your app can always retrieve and sometimes manage file attributes and file permissions. By default, any files your app creates are owned by the current user and given appropriate permissions.

File System Programming Guide is the repository of definitive information on file attributes, file permissions, standard system directories, and anything else related to the OS X file system.

A Few Important System Directories

When writing and reading files of various types, you should understand and follow the conventions of the OS X file system, which expects related files and data in specific places. Knowing where to put files and how to get information out of the file system ensures a better user experience. And it is important if you are distributing your app through the Mac App Store, because the Store expects to find your app’s data files in specific directories.

Table 1 lists the directories with which apps commonly interact. Note that home directories (which you might see preceded with a tilde (~) character in places) can have a standard directory of the same name as a system (non-user) directory.

Table 1  Key directories for OS X apps

Directory

Description

Applications

Is the installation directory for applications, whether global /Applications or in a user’s home directory. To access resources inside your application bundle, use an NSBundle object instead.

Home directory

Contains the logged-in user’s files. It is the app’s container directory if the app is running in a sandbox (described in “Security,” below). Otherwise, it a user-specific subdirectory of /Users.

Library

Stores private app-related data and preferences. There are Library directories at the top level and in the user’s home directory. Always use the one located inside the current home directory. In recent versions of OS X, the Finder hides the Library directory in the user’s home folder by default. Therefore, you should never store files in this directory that you want the user to access.

Application Support

Is a subdirectory of Library for storing any file that supports an app but is not required for the app to run, such as document templates or configuration files. The files should never contain user data and should be in a subdirectory named for your app or company.

Caches

Stores cache files and other temporary data that your app can re-create as needed. This directory is located inside the Library directory. Put the files in a subdirectory of Caches that is named for your app or company. Your app is responsible for cleaning out these data files when they are no longer needed.

Temporary directory

Stores files that do not need to persist between launches of your app (for example, scratch files). This directory is typically hidden from the user.

Because the actual paths to standard file-system directories can differ based on certain conditions, you should use the URLsForDirectory:inDomains: method of the NSFileManager class to retrieve the actual directory path. You can then add any custom directory and filename information to the returned URL object to complete the path. Construct paths using the methods of the NSURL class.

Coordinating File Access with Other Processes

In OS X, other processes might access the same files that your app does. Therefore, when working with files, you should use the file coordination API so you can be notified when other processes (including the Finder) attempt to read or modify files your app is currently using.

Coordinating file access is critical when your app adopts iCloud storage, because multiple apps can access your document files in iCloud. The simplest way to incorporate file coordination into your app is to use the NSDocument class, which handles all of the file-related management for you. On the other hand, if you're writing a library-style (or “shoebox”) app, you must use the file coordination interfaces directly.

Document-Based App Programming Guide for Mac describes how to override the NSDocument class and File System Programming Guide contains information on directly calling the file coordination methods.

Security

The security technologies in OS X help you safeguard sensitive data created or managed by your app. They also help minimize damage caused by attacks from hostile code. These technologies impact how your app interacts with system resources and the file system.

App Sandbox and XPC

App Sandbox defends against stolen, corrupted, or deleted user data if malicious code exploits your app. App Sandbox also minimizes the damage from coding errors. Its strategy is twofold:

  1. App Sandbox enables you to describe how your app interacts with the system. The system then grants your app the access it needs to get its job done, and no more. For your app to provide the highest level of damage containment, the best practice is to request as few entitlements as possible.

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

Some app operations are more likely to be targets of malicious exploitation—for example if they parse data received over a network or decode video frames. XPC is an interprocess communication technology that complements App Sandbox by enabling privilege separation. By using XPC, you can improve the effectiveness of the damage containment offered by App Sandbox by separating such potentially dangerous activities into their own address spaces. Privilege separation, in turn, is a development strategy in which you divide an app into pieces according to the system resource access that each piece needs. The component pieces that you create are called XPC services.

App Sandbox Design Guide gives a complete explanation of App Sandbox and how to use it. Daemons and Services Programming Guide provides details on adopting XPC.

Code Signing

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

In Xcode you can typically rely on automatic code signing, which requires only that you specify a code signing identity in the build settings for your project. Tools Workflow Guide for Mac describes how to do this.

The Keychain

A keychain is a secure, encrypted container for storing a user’s passwords and other secrets. It is designed to help a user manage their multiple logins, each with its own ID and password. You should always use a keychain to store sensitive credentials for your app. Keychain Services Programming Guide describes keychains in detail.