iOS Reference Library Apple Developer
Search

Implementing Standard Application Behaviors

There are two standard behaviors that you should always implement for an iOS application and there are others that you may want to implement depending on your needs. The two you should always implement are:

This chapter provides examples of these and other common application behaviors and offers guidance on how best to implement those behaviors. This chapter also demonstrates the proper way to implement common tasks that all applications typically need to perform.

Observing Low-Memory Warnings

When the system dispatches a low-memory warning to your application, heed it. iOS notifies the frontmost application whenever the amount of free memory dips below a safe threshold. If your application receives this warning, it must free up as much memory as it can by releasing objects it does not need or clearing out memory caches that it can easily recreate later.

UIKit provides several ways to receive low-memory warnings, including the following:

Upon receiving any of these warnings, your handler method should respond by immediately freeing up any unneeded memory. For example, the UIViewController class responds by automatically purging its view if that view is not currently visible; subclasses can supplement the default behavior by purging additional data structures. An application that maintains a cache of images might respond by releasing any images that are not currently onscreen.

If your custom objects have known purgeable resources, you can have those objects register for the UIApplicationDidReceiveMemoryWarningNotification notification and release their purgeable resources directly. Have these objects register if you have a few objects that manage most of your purgeable resources and if it is appropriate to purge all of those resources. But if you have many purgeable objects or want to coordinate the release of only a subset of those objects, you might want to use your application delegate to release the desired objects.

Important: Like the system applications, your applications should always handle low-memory warnings. System applications consume small amounts of memory while processing requests. When a low-memory condition is detected, the system delivers low-memory warnings to all running programs (including your application) and may terminate some background applications (if necessary) to ease memory pressure. If not enough memory is released‚Äîperhaps because your application is leaking or still consuming too much memory‚Äîthe system may still terminate your application.

You can test your application’s behavior under low-memory conditions using the Simulate Memory Warning command in the simulator.

Preserving the Application’s Current State

Whenever your application moves to the background, you need to save to disk any data that might be lost if something were to happen to your application. Background applications can be purged by the system at any time if memory pressure becomes strong enough. Suspended applications are usually purged first but other applications can be purged too, especially if they consume large amounts of memory themselves. Writing out any unsaved user data or application state information ensures that your application has enough data to restore itself to current state upon a subsequent relaunch.

In addition to writing out data when moving to the background, your application should also save changes to user data at key points in your workflow. Unlike most desktop applications, there is no save command in an iOS application. Therefore changes made by the user need to be written out to disk at the point where the user makes or confirms the change. Under no circumstances should you let the user navigate to a new page of content without saving data on the current page first.

Saving the state of your application’s user interface and data structures is also something you should do to improve the user experience. Because iOS applications are meant to be launched and used quickly, restoring your application to the state it was in when it was last run provides a continuity between launches. You do not necessarily have to return the user to the exact same screen as before, but you should return the user to the most logical starting point. For example, if a user edits a contact and then leaves the Phone application, upon returning, the Phone application displays the top-level list of contacts, rather than the editing screen for the contact.

Launching in Landscape Mode

Applications in iOS normally launch in portrait mode to match the orientation of the Home screen. If you have an application that runs in both portrait and landscape mode, your application should always launch in portrait mode initially and then let its view controllers rotate the interface as needed based on the device’s orientation. If your application runs in landscape mode only, however, you must perform the following steps to make it launch in a landscape orientation initially:

Important: The preceding steps assume your application uses view controllers to manage its view hierarchy. View controllers provide a significant amount of infrastructure for handling orientation changes as well as other complex view-related events. If your application is not using view controllers‚Äîas may be the case with games and other OpenGL ES‚Äìbased applications‚Äîyou are responsible for rotating the drawing surface (or adjusting your drawing commands) as needed to present your content in landscape mode.

The UIInterfaceOrientation property hints to iOS that it should configure the orientation of the application status bar (if one is displayed) as well as the orientation of views managed by any view controllers at launch time. In iOS 2.1 and later, view controllers respect this property and set their view’s initial orientation to match. Using this property is also equivalent to calling the setStatusBarOrientation:animated: method of UIApplication early in the execution of your applicationDidFinishLaunching: method.

Note: To launch a view controller‚Äìbased application in landscape mode in versions of iOS prior to v2.1, you need to apply a 90-degree rotation to the transform of the application‚Äôs root view in addition to all the preceding steps. Prior to iOS 2.1, view controllers did not automatically rotate their views based on the value of the UIInterfaceOrientation key.

Files and the File System

Every application has a protected area in which it can create and modify files. In addition, the system allows applications to share files with each other (and with the user) through well-defined and secure means. However, supporting those means requires work on your part. The following sections describe the types of file-related operations you can perform in your applications.

Getting Paths to Application Directories

At various levels of the system, there are programmatic ways to obtain file-system paths to the directory locations of an application’s sandbox. However, the preferred way to retrieve these paths is with the Cocoa programming interfaces.

You can use the NSSearchPathForDirectoriesInDomains function to get exact paths to your Documents and Caches directories. To get a path to the tmp directory, us the NSTemporaryDirectory function. When you have one of these “base” paths, you can use the path-related methods of NSString to modify the path information or create new path strings. For example, upon retrieving the temporary directory path, you could append a file name and use the resulting string to create a file with the given name in the temporary directory.

Note: If you are using frameworks with ANSI C programmatic interfaces‚Äîincluding those that take paths‚Äîrecall that NSString objects are ‚Äútoll-free bridged‚Äù with their Core Foundation counterparts. This means that you can cast a NSString object (such as the return by one of the above functions) to a CFStringRef type, as shown in the following example:

CFStringRef tmpDirectory = (CFStringRef)NSTemporaryDirectory();

The NSSearchPathForDirectoriesInDomains function of the Foundation framework lets you obtain the full path to several application-related directories. To use this function in iOS, specify an appropriate search path constant for the first parameter and NSUserDomainMask for the second parameter. Table 3-1 lists several of the most commonly used constants and the directories they return.

Table 3-1  Commonly used search path constants

Constant

Directory

NSDocumentDirectory

<Application_Home>/Documents

NSCachesDirectory

<Application_Home>/Library/Caches

NSApplicationSupportDirectory

<Application_Home>/Library/Application Support

Because the NSSearchPathForDirectoriesInDomains function was designed originally for Mac OS X, where multiple such directories could exist, it returns an array of paths rather than a single path. In iOS, the resulting array should contain the single path to the desired directory. Listing 3-1 shows a typical use of this function.

Listing 3-1  Getting the path to the application‚Äôs Documents directory

NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];

You can call NSSearchPathForDirectoriesInDomains using a domain-mask parameter other than NSUserDomainMask or a directory constant other than those in Table 3-1, but the application will be unable to write to any of the returned directory locations. For example, if you specify NSApplicationDirectory as the directory parameter and NSSystemDomainMask as the domain-mask parameter, you get the path /Applications returned (on the device), but your application cannot write any files to this location.

Another consideration to keep in mind is the difference in directory locations between platforms. The paths returned by the NSSearchPathForDirectoriesInDomains function differ depending on whether you’re running your application on the device or on the simulator. For example, take the function call shown in Listing 3-1. On the device, the returned path (documentsDirectory) is similar to the following:

/var/mobile/Applications/30B51836-D2DD-43AA-BCB4-9D4DADFED6A2/Documents

However, on the Simulator, the returned path takes the following form:

/Volumes/Stuff/Users/johnDoe/Library/Application Support/iPhone Simulator/User/Applications/118086A0-FAAF-4CD4-9A0F-CD5E8D287270/Documents

To read and write user preferences, use the NSUserDefaults class or the CFPreferences API. These interfaces eliminate the need for you to construct a path to the Library/Preferences/ directory and read and write preference files directly. For more information on using these interfaces, see “Adding the Settings Bundle.”

If your application contains sound, image, or other resources in the application bundle, you should use the NSBundle class or CFBundleRef opaque type to load those resources. Bundles have an inherent knowledge of where resources live inside the application. In addition, bundles are aware of the user’s language preferences and are able to choose localized resources over default resources automatically. For more information on bundles, see “The Application Bundle.”

Sharing Files with the User

Applications that want to make user data files accessible can do so using application file sharing. File sharing enables the application to expose the contents of its /Documents directory to the user through iTunes. The user can then move files back and forth between the device and a desktop computer. This feature does not allow your application to share files with other applications on the same device, though. To share data and files between applications, you must the pasteboard or a document interaction controller object.

To enable file sharing for your application, do the following:

  1. Add the UIFileSharingEnabled key to your application’s Info.plist file and set the value of the key to YES.

  2. Put whatever files you want to share in your application’s Documents directory.

  3. When the device is plugged into the user’s computer, iTunes 9.1 displays a File Sharing section in the Apps tab of the selected device.

  4. The user can add files to this directory or move files to the desktop.

Applications that support file sharing should be able to recognize when files have been added to the Documents directory and respond appropriately. For example, your application might make the contents of any new files available from its interface. You should never present the user with the list of files in this directory and ask them to decide what to do with those files.

Important: In iTunes, users can manipulate only the top-level items in the Documents directory. Users cannot see the contents of subdirectories but can delete those directories or copy their contents to the desktop. You should take this into consideration when deciding where to put files in this directory.

Working with Protected Files

When file protection is enabled on a device, applications can mark files as protected for greater security. If you plan to support this feature in your applications, though, you must also be prepare your application to handle situations where the protected file is unavailable. The following sections show you how to add protection to files and how to modify your application to work with protected files.

Marking a File as Protected

To mark a file as protected, you must add an extended attribute to it. The Foundation framework includes two ways to add this attribute:

Note: If you are working with NSData objects already, using the writeToFile:options:error: method to save and protect that data in one step is recommended. This guarantees that the data is always stored on disk in an encrypted format.

Adding protection to a file is a one-way operation—once added, you cannot remove the attribute. When adding this attribute to new files, it is recommended that you add this attribute after you create the file but before you write any data to it. (If you are writing out the contents of an NSData object, this happens automatically.) When adding this attribute to existing (unprotected) files, adding this key replaces the unprotected file with a protected version.

Determining the Availability of Protected Files

A protected file can be accessed only when a device is unlocked. Because applications may continue running while a device is locked, your code should be prepared to handle the possibility of protected files becoming unavailable at any time. The UIKit framework provides ways to track whether data protection is currently enabled.

Any application that works with protected files should implement the application delegate methods. When the applicationProtectedDataWillBecomeUnavailable: method is called, your application should immediately close any protected files and refrain from using them again until the applicationProtectedDataDidBecomeAvailable: method is called. Any attempts to access the protected files while they are unavailable will fail.

Opening Files Whose Type is Unknown

When your application needs to interact with files of unknown types, you can use a UIDocumentInteractionController object to manage those interactions. A document interaction controller works with the system to determine whether files can be previewed in place or opened by another application. Your application works with the document interaction controller to present the available options to the user at appropriate times.

To use a document interaction controller in your application, do the following:

  1. Create an instance of the UIDocumentInteractionController class for each file you want to manage.

  2. Present the file in your application’s user interface. (Typically, you would do this by displaying the file name or icon somewhere in your interface.)

  3. When the user interacts with the file, ask the document interaction controller to present one of the following interfaces:

    • A file preview view that displays the contents of the file

    • A menu containing options to preview the file, copy its contents, or open it using another application

    • A menu prompting the user to open it with another application

Any application that interacts with files can use a document interaction controller. Programs that download files from the network are the most likely candidates to need these capabilities. For example, an email program might use document interaction controllers to preview or open files attached to an email. Of course, you do not need to download files from the network to use this feature.

Creating and Configuring a Document Interaction Controller

To create a new document interaction controller, initialize a new instance of the UIDocumentInteractionController class with the file you want it to manage and assign an appropriate delegate object. Your delegate object is responsible for providing the document interaction controller with information it needs to present its views. You can also use the delegate to perform additional actions when those views are displayed. The following code creates a new document interaction controller and sets the delegate to the current object. Note that the caller of this method needs to retain the returned object.

- (UIDocumentInteractionController*)docControllerForFile:(NSURL*)fileURL
{
   UIDocumentInteractionController* docController =
       [UIDocumentInteractionController interactionControllerWithURL:fileURL];
   docController.delegate = self;
 
   return docController;
}

Once you have a document interaction controller object, you can use its properties to get information about the file, including its name, type information, and path information. The controller also has an icons property that contains UIImage objects representing the document’s icon in various sizes. You can use all of this information when presenting the document in your user interface.

If you plan to let the user open the file in another application, you can use the annotation property of the document interaction controller to pass custom information to the opening application. It is up to you to provide information in a format that the other application will recognize. For example, this property is typically used by application suites that want to communicate additional information about a file to other applications in the suite. The opening application sees the annotation data in the UIApplicationLaunchOptionsAnnotationKey key of the options dictionary that is passed to it at launch time.

Presenting a Document Interaction Controller

When the user interacts with a file, you use the document interaction controller to display the appropriate user interface. You have the choice of displaying a document preview or of prompting the user to choose an appropriate action for the file using one of the following methods:

Each of the preceding methods attempts to display a custom view with the appropriate content. When calling these methods, you should always check the return value to see if the attempt was actually successful. These methods may return NO if the resulting interface would have contained no content. For example, the presentOpenInMenuFromRect:inView:animated: method returns NO if there are no applications capable of opening the file.

If you choose a method that might display a preview of the file, your delegate object must implement the documentInteractionControllerViewControllerForPreview: method. Most document previews are displayed using a modal view, so the view controller you return becomes the parent of the modal document preview. (If you return a navigation controller, the document interaction controller is pushed onto its navigation stack instead.) If you do not implement this method, if your implementation returns nil, or if the specified view controller is unable to present the document interaction controller, a document preview is not displayed.

Normally, the document interaction controller automatically handles the dismissal of the view it presents. However, you can dismiss the view programmatically as needed by calling the dismissMenuAnimated: or dismissPreviewAnimated: methods.

Implementing Support for Custom File Formats

Applications that are able to open specific document or file formats may register those formats with the system. When the system or another application needs to open a file, it can hand that file off to your application to do so. In order to support custom file formats, your application must:

  1. Register the file types your application supports with the system.

  2. Implement the proper methods to open files (when asked to do so by the system).

Registering the File Types Your Application Supports

If your application is capable of opening specific types of files, you should register those types with the system. To declare support for file types, your application must include the CFBundleDocumentTypes key in its Info.plist file. The system gathers this information from your application and maintains a registry that other applications can access through a document interaction controller.

The CFBundleDocumentTypes key contains an array of dictionaries, each of which identifies information about a specific document type. A document type usually has a one-to-one correspondence with a particular document type. However, if your application treats more than one file type the same way, you can group those types together as a single document type. For example, if you have two different file formats for your application’s native document type, you could group both the old type and new type together in a single document type entry. By doing so, both the new and old files would appear to be the same type of file and would be treated in the same way.

Each dictionary in the CFBundleDocumentTypes array can include the following keys:

From the perspective of your application, a document is a file type (or file types) that the application supports and treats as a single entity. For example, an image processing application might treat different image file formats as different document types so that it can fine tune the behavior associated with each one. Conversely, a word processing application might not care about the underlying image formats and just manage all image formats using a single document type.

Table 6-2 shows a sample XML snippet from the Info.plist of an application that is capable of opening a custom file type. The LSItemContentTypes key identifies the UTI associated with the file format and the CFBundleTypeIconFiles key points to the icon resources to use when displaying it.

Listing 3-2  Document type information for a custom file format

<dict>
   <key>CFBundleTypeName</key>
   <string>My File Format</string>
   <key>CFBundleTypeIconFiles</key>
       <array>
           <string>MySmallIcon.png</string>
           <string>MyLargeIcon.png</string>
       </array>
   <key>LSItemContentTypes</key>
       <array>
           <string>com.example.myformat</string>
       </array>
   <key>LSHandlerRank</key>
   <string>Owner</string>
</dict>

For more information about the contents of the CFBundleDocumentTypes key, see the description of that key in Information Property List Key Reference.

Opening Supported File Types

The system may ask your application to open a specific file and present it to the user at any time. Requests to open another document might cause your application to be launched or, if your application is already running in the background, cause it to move to the foreground. In both cases, the system provides information about the file to be opened to your application delegate.

There are two application delegate methods to implement for handling the opening of a file:

The application:didFinishLaunchingWithOptions: method is called only when your application needs to be launched to open a file. Your implementation of this method should retrieve any relevant keys from the options dictionary and use them to decide if it should open the file. You typically do not open the file in this method, though. Instead, you return YES to indicate that your application is able to open the file. If you return YES, the system calls your application:handleOpenURL: method to open the file. However, if you return NO, the application:handleOpenURL: method is not called.

The options dictionary for the application:didFinishLaunchingWithOptions: method may contain several keys with information about the file and the application that asked for it to be opened. Specifically, this dictionary may contain the following keys:

Modifying Documents Passed to Your Application by the System

When you use a UIDocumentInteractionController to open a file, the system transfers the file to the ~/Documents/Inbox directory of the application asked to open it. Because the Inbox directory is managed by the system, only the system is allowed to write to it. The application opening the file has read-only access to the file and cannot write to it.

If your application allows the user to edit documents passed to it by a document interaction controller, you must copy those documents to a writable directory before attempting to save any changes. Do not copy a file out of the Inbox directory until the user actually makes a change to it. And the process of copying files out of the Inbox directory (and to a writable directory) should be transparent to the user. You should not prompt the user about whether to save the file to a different location.

Communicating with Other Applications

If an application handles URLs of a known type, you can use that URL scheme to communicate with the application. In most cases, however, URLs are used simply to launch another application and have it display some information that is relevant to your own application. For example, if your application manages address information, you could send a URL containing a given address to the Maps application to show that location. This level of communication creates a much more integrated environment for the user and alleviates the need for your application to implement features that exist elsewhere on the device.

Apple provides built-in support for the http, mailto, tel, and sms URL schemes. It also supports http–based URLs targeted at the Maps, YouTube, and iPod applications. Applications can register their own custom URL schemes as well. To communicate with an application, create an NSURL object with some properly formatted content and pass it to the openURL: method of the shared UIApplication object. The openURL: method launches the application that has registered to receive URLs of that type and passes it the URL. When the user subsequently quits that application, the system often relaunches your application but may not always do so. The decision to relaunch an application is made based on the user’s actions in the handler application and whether returning to your application would make sense from the user’s perspective.

The following code fragment illustrates how one application can request the services of another application (“todolist” in this example is a hypothetical custom scheme registered by an application):

NSURL *myURL = [NSURL URLWithString:@"todolist://www.acme.com?Quarterly%20Report#200806231300"];
[[UIApplication sharedApplication] openURL:myURL];

Important: If your URL type includes a scheme that is identical to one defined by Apple, the Apple-provided application is launched instead of your application. If multiple third-party applications register to handle the same URL scheme, it is undefined as to which of the applications is picked to handle URLs of that type.

If your application defines its own custom URL scheme, it should implement a handler for that scheme as described in “Implementing Custom URL Schemes.” For more information about the system-supported URL schemes, including information about how to format the URLs, see Apple URL Scheme Reference.

Implementing Custom URL Schemes

You can register URL types for your application that include custom URL schemes. A custom URL scheme is a mechanism through which third-party applications can interact with each other and with the system. Through a custom URL scheme, an application can make its services available to other applications.

Registering Custom URL Schemes

To register a URL type for your application, you must specify the subproperties of the CFBundleURLTypes property, which was introduced in “The Information Property List.” The CFBundleURLTypes property is an array of dictionaries in the application’s Info.plist file, with each dictionary defining a URL type the application supports. Table 3-2 describes the keys and values of a CFBundleURLTypes dictionary.

Table 3-2  Keys and values of the CFBundleURLTypes property

Key

Value

CFBundleURLName

A string that is the abstract name for the URL type. To ensure uniqueness, it is recommended that you specify a reverse-DNS style of identifier, for example, com.acme.myscheme.

The URL-type name provided here is used as a key to a localized string in the InfoPlist.strings file in a language-localized bundle subdirectory. The localized string is the human-readable name of the URL type in a given language.

CFBundleURLSchemes

An array of URL schemes for URLs belonging to this URL type. Each scheme is a string. URLs belonging to a given URL type are characterized by their scheme components.

Figure 3-1 shows the Info.plist file of an application being edited using the built-in Xcode editor. In this figure, the URL types entry in the left column is equivalent to the CFBundleURLTypes key you would add directly to an Info.plist file. Similarly, the “URL identifier” and “URL Schemes” entries are equivalent to the CFBundleURLName and CFBundleURLSchemes keys.

Figure 3-1  Defining a custom URL scheme in the Info.plist file

Defining a custom URL scheme in the Info.plist file

After you have registered a URL type with a custom scheme by defining the CFBundleURLTypes property, you can test the scheme in the following way:

  1. Build, install, and run your application.

  2. Go to the Home screen and launch Safari. (In the simulator, you can go to the Home screen by selecting Hardware > Home from the menu.)

  3. In the address bar of Safari, type a URL that uses your custom scheme.

  4. Verify that your application launches and that the application delegate is sent a application:handleOpenURL: message.

Handling URL Requests

An application that has its own custom URL scheme must be able to handle URLs passed to it. All URLs are passed to your application delegate for handling and the URL can be passed in when your application is launched or while it is running in the background. How your application is notified of a URL to open depends on its current state:

Note: When your application launches because of a request to open a URL, you can display a custom launch image for each scheme you define. For more information about how to specify these launch images, see ‚ÄúProviding Launch Images for Custom URL Schemes.‚Äù

All URLs are passed to your application in an NSURL object. It is up to you to define the format of the URL contents, but the NSURL class conforms to the RFC 1808 specification and therefore supports most URL formatting conventions. Specifically, it includes methods that return the various parts of a URL as defined by RFC 1808, including the user, password, query, fragment, and parameter strings. The “protocol” for your custom scheme can use these URL parts for conveying various kinds of information.

In the implementation of application:handleOpenURL: shown in Listing 3-3, the passed-in URL object conveys application-specific information in its query and fragment parts. The delegate extracts this information—in this case, the name of a to-do task and the date the task is due—and with it creates a model object of the application.

Listing 3-3  Handling a URL request based on a custom scheme

- (BOOL)application:(UIApplication *)application handleOpenURL:(NSURL *)url {
    if ([[url scheme] isEqualToString:@"todolist"]) {
        ToDoItem *item = [[ToDoItem alloc] init];
        NSString *taskName = [url query];
        if (!taskName || ![self isValidTaskString:taskName]) { // must have a task name
            [item release];
            return NO;
        }
        taskName = [taskName stringByReplacingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
 
        item.toDoTask = taskName;
        NSString *dateString = [url fragment];
        if (!dateString || [dateString isEqualToString:@"today"]) {
            item.dateDue = [NSDate date];
        } else {
            if (![self isValidDateString:dateString]) {
                [item release];
                return NO;
            }
            // format: yyyymmddhhmm (24-hour clock)
            NSString *curStr = [dateString substringWithRange:NSMakeRange(0, 4)];
            NSInteger yeardigit = [curStr integerValue];
            curStr = [dateString substringWithRange:NSMakeRange(4, 2)];
            NSInteger monthdigit = [curStr integerValue];
            curStr = [dateString substringWithRange:NSMakeRange(6, 2)];
            NSInteger daydigit = [curStr integerValue];
            curStr = [dateString substringWithRange:NSMakeRange(8, 2)];
            NSInteger hourdigit = [curStr integerValue];
            curStr = [dateString substringWithRange:NSMakeRange(10, 2)];
            NSInteger minutedigit = [curStr integerValue];
 
            NSDateComponents *dateComps = [[NSDateComponents alloc] init];
            [dateComps setYear:yeardigit];
            [dateComps setMonth:monthdigit];
            [dateComps setDay:daydigit];
            [dateComps setHour:hourdigit];
            [dateComps setMinute:minutedigit];
            NSCalendar *calendar = [NSCalendar currentCalendar];
            NSDate *itemDate = [calendar dateFromComponents:dateComps];
            if (!itemDate) {
                [dateComps release];
                [item release];
                return NO;
            }
            item.dateDue = itemDate;
            [dateComps release];
        }
 
        [(NSMutableArray *)self.list addObject:item];
        [item release];
        return YES;
    }
    return NO;
}

Be sure to validate the input you get from URLs passed to your application; see “Validating Input” in Secure Coding Guide to find out how to avoid problems related to URL handling. To learn about URL schemes defined by Apple, see Apple URL Scheme Reference.

Displaying Application Preferences

If your application uses preferences to control various aspects of its behavior, how you expose those preferences to the user depends on how integral they are to your program.

When determining whether a set of preferences is integral, think about the intended usage pattern. If you expect the user to make changes to preferences somewhat frequently, or if those preferences play a relatively important role in how the application behaves, they are probably integral. For example, the settings in a game are usually integral to playing the game and something the user might want to change quickly. Because the Settings application is a separate application, however, you would use it only for preferences that you do not expect the user to access frequently.

If you choose to implement preferences inside your application, it is up to you to define the interface and write the code to manage those preferences. If you choose to use the Settings application, however, your application must provide a Settings bundle to manage them.

A settings bundle is a custom resource that you include in the top level of your application’s bundle directory. An opaque directory with the name Settings.bundle, the settings bundle contains specially formatted data files (and supporting resources) that tell the Settings application how to display your preferences. These files also tell the Settings application where to store the resulting values in the preferences database, which your application then accesses using the NSUserDefaults or CFPreferences APIs.

If you implement your preferences using a settings bundle, you should also provide a custom icon for your preferences. The Settings application displays the image you provide next to your application name. For information about application icons and how you specify them, see “Application Icons.”

For more information about creating a Settings bundle for your application, see “Implementing Application Preferences.”

Turning Off Screen Locking

If an iOS-based device does not receive touch events for a specified period of time, it turns off the screen and disables the touch sensor. Locking the screen in this way is an important way to save power. As a result, you should leave this feature enabled except when absolutely necessary to prevent unintended behavior in your application. For example, you might disable screen locking if your application does not receive screen events regularly but instead uses other features (such as the accelerometers) for input.

To disable screen locking, set the idleTimerDisabled property of the shared UIApplication object to YES. Be sure to reset this property to NO at times when your application does not need to prevent screen locking. For example, you might disable screen locking while the user is playing a game, but you should reenable it when the user is in setup screens or is otherwise not actively playing the game.




Last updated: 2010-06-30

Did this document help you? Yes It's good, but... Not helpful...