The runtime environment of iOS is designed for the fast and secure execution of programs. The following sections describe the key aspects of this runtime environment and provide guidance on how applications can best operate within it.
The strength of iOS-based devices is their immediacy. A typical user pulls a device out of a pocket or bag and uses it for a few seconds, or maybe a few minutes, before putting it away again. The user might be taking a phone call, looking up a contact, changing the current song, or getting some piece of information during that time. Your own applications need to reflect that sense of immediacy by launching and getting up and running quickly. If your application takes a long time to launch, the user may be less inclined to use it.
In iOS, the user interacts with only one application at a time. Thus, as each new application is launched, the previous application’s user interface goes away. Prior to iOS 4, this meant that the application itself was quit and removed from memory. However, in iOS 4 and later, quitting an application causes it to move into the background. Applications remain in the background until they are launched again or until the system needs to reclaim the memory they are using.
The ability to run in the background means that relaunching an application is much faster. When it moves to the background, an application’s objects remain in memory and in most cases the application itself enters a suspended state of execution. When the user relaunches the application, it simply resumes from the exact point where it was without having to reload its user interface and restore itself to its previous state.
Even though applications can run in the background, they are not guaranteed to do so forever. As memory becomes constrained, the system purges applications that have not been launched recently. Because this can happen at any time, and in some cases with no notice, your application should still save information about your application’s current state in addition to any unsaved data when it moves to the background. If it ever needs to be relaunched, it can use this information to restore itself to the previous state and make it look like it was always running. Doing so provides a more consistent user experience by putting the user right back where they were when they last used your application.
For the most part, iOS has the same features and behaves in the same way as Mac OS X. However, there are places where the behavior of iOS differs from Mac OS X.
To manage program memory, iOS uses essentially the same virtual memory system found in Mac OS X. In iOS, each program still has its own virtual address space, but (unlike Mac OS X) its usable virtual memory is constrained by the amount of physical memory available. This is because iOS does not write volatile pages to disk when memory gets full. Instead, the virtual memory system frees up volatile memory, as needed, to make sure the running application has the space it needs. It does this by removing memory pages that are not being used and that contain read-only contents, such as code pages. Such pages can always be loaded back into memory later if they are needed again.
If memory continues to be constrained, the system may also send notifications to the running applications, asking them to free up additional memory. All applications should respond to this notification and do their part to help relieve the memory pressure. For information on how to handle such notifications in your application, see “Observing Low-Memory Warnings.”
One way iOS attempts to save power is through the automatic sleep timer. If the system does not detect touch events for an extended period of time, it dims the screen initially and eventually turns it off altogether. Although most developers should leave this timer on, game developers and developers whose applications do not use touch inputs can disable this timer to prevent the screen from dimming while their application is running. To disable the timer, set the idleTimerDisabled
property of the shared UIApplication
object to YES
.
Because it results in greater power consumption, disabling the sleep timer should be avoided at all costs. The only applications that should consider using it are mapping applications, games, or applications that do not rely on touch inputs but do need to display visual content on the device’s screen. Audio applications do not need to disable the timer because audio content continues to play even after the screen dims. If you do disable the timer, be sure to reenable it as soon as possible to give the system the option to conserve more power. For additional tips on how to save power in your application, see “Reduce Power Consumption.”
In iOS 4 and later, applications can perform tasks while running in the background. When the user quits an application, instead of its process being terminated, the application is moved to the background. Shortly after moving to the background, most applications are suspended so that they do not run and consume additional power. However, applications that need to continue running can ask the system for the execution time to do so.
Regardless of whether an application is running in the background or suspended, the fact that the application is still in memory means that relaunching the application takes much less time. An application’s objects (including its windows and views) normally remain in memory and therefore do not need to be recreated when the application is subsequently relaunched by the user. However, if memory becomes constrained, the system may purge background applications to make more room for the foreground application. To appear consistent with the application remaining in the background at all times, an application should store information about its current state when it moves to the background and be able to restore itself to that state upon a subsequent relaunch.
For an overview of multitasking and what you need to do to support it, see “Multitasking.”
An important job of iOS is to ensure the security of the user’s device and the applications running on it. To this end, iOS implements several features to ensure the integrity of the user’s data and to ensure that applications do not interfere with one another or the system.
For security reasons, iOS restricts an application (including its preferences and data) to a unique location in the file system. This restriction is part of the security feature known as the application’s “sandbox.” The sandbox is a set of fine-grained controls limiting an application’s access to files, preferences, network resources, hardware, and so on. In iOS, an application and its data reside in a secure location that no other application can access. When an application is installed, the system computes a unique opaque identifier for the application. Using a root application directory and this identifier, the system constructs a path to the application’s home directory. Thus an application’s home directory could be depicted as having the following structure:
/
ApplicationRoot/
ApplicationID/
During the installation process, the system creates the application’s home directory and several key subdirectories, configures the application sandbox, and copies the application bundle to the home directory. The use of a unique location for each application and its data simplifies backup-and-restore operations, application updates, and uninstallation. For more information about the application-specific directories created for each application, see “A Few Important Application Directories.” For information about application updates and backup-and-restore operations, see “Backup and Restore.”
Important: The sandbox limits the damage an attacker can cause to other applications and to the system, but it cannot prevent attacks from happening. In other words, the sandbox does not protect your application from direct attacks by malicious entities. For example, if there is an exploitable buffer overflow in your input-handling code and you fail to validate user input, an attacker might still be able to crash your program or use it to execute the attacker’s code.
In iOS 4 and later, applications can use file protection to encrypt files and make them inaccessible when the user’s device is locked. File protection takes advantage of built-in encryption hardware on specific devices (such as the iPhone 3GS) to add a level of security for applications that work with sensitive data. Protected files are stored on disk in an encrypted format at all times. While the user’s device is locked, not even the owning application can access the data in the encrypted files. The user must explicitly unlock the device (by entering the appropriate passcode) before the application can retrieve the decrypted data from the files.
Protecting files on a device requires several steps:
The file system on the user’s device must be formatted to support file protection. For existing devices, this requires the user to reformat the device and restore any content from a backup.
The user’s device must have the passcode lock setting enabled and a valid passcode set.
Applications must designate which data files need to be protected and assign the appropriate metadata attributes to them; see “Marking a File as Protected.”
Applications must respond appropriately to situations where a file may become locked; see “Determining the Availability of Protected Files.”
It is up to you to decide which files your application should mark as protected. Applications must enable file protection on a file-by-file basis, and once enabled those protections cannot be removed. Also, applications should be prepared to deal with situations where data files should be protected but are not currently. This could happen if the user restored a device from an earlier backup where file protections were not yet added.
For more information about implementing support for file protection in your application, see “Working with Protected Files.”
A keychain is a secure, encrypted container for passwords and other secrets. The keychain data for an application is stored outside of the application sandbox. If an application is uninstalled, that data is automatically removed. When the user backs up application data using iTunes, the keychain data is also backed up. However, it can only be restored to the device from which the backup was made. An upgrade of an application does not affect its keychain data.
For more on the iOS keychain, see “Keychain Services Concepts” in Keychain Services Programming Guide.
Your application and any files it creates share space with the user’s media and personal files on the flash-based memory. An application can access its using the local file system, which behaves like any other file system and is accessed using standard system routines. The following sections describe several things you should be aware of when accessing the local file system.
For security purposes, an application has only a few locations in which it can write its data and preferences. When an application is installed on a device, a home directory is created for the application. Table 1-1 lists some of the important subdirectories inside the home directory that you might need to access. This table describes the intended usage and access restrictions for each directory and points out whether the directory’s contents are backed up by iTunes. For more information about the application home directory itself, see “The Application Sandbox.”
Directory | Description |
---|---|
<Application_Home> | This is the bundle directory containing the application itself. Because an application must be signed, you must not make changes to the contents of this directory at runtime. Doing so may prevent your application from launching later. In iOS 2.1 and later, the contents of this directory are not backed up by iTunes. However, iTunes does perform an initial sync of any applications purchased from the App Store. |
<Application_Home> | Use this directory to store user documents and application data files. The contents of this directory can be made available to the user through file sharing, which is described in “Sharing Files with the User’s Desktop Computer.” The contents of this directory are backed up by iTunes. |
<Application_Home> | This directory contains application-specific preference files. You should not create preferences files directly but should instead use the The contents of this directory are backed up by iTunes. |
<Application_Home> | Use this directory to write any application-specific support files that you want to persist between launches of the application. Your application is generally responsible for adding and removing these files. However, iTunes removes these files during a full restore of the device so you should be able to recreate them as needed. In iOS 2.2 and later, the contents of this directory are not backed up by iTunes. |
<Application_Home> | Use this directory to write temporary files that you do not need to persist between launches of your application. Your application should remove files from this directory when it determines they are no longer needed. (The system may also purge lingering files from this directory when your application is not running.) In iOS 2.1 and later, the contents of this directory are not backed up by iTunes. |
For information about how to get the path of specific directories, see “Getting Paths to Application Directories.” For detailed information about which application directories are backed up, see “What Is Backed Up?.”
The file system for iOS-based devices is case sensitive. Whenever you work with filenames, you should be sure that the case matches exactly or your code may be unable to open or access the file.
Applications that want to make user data files accessible can do so using application file sharing. File sharing enables the sharing of files between your application and the user’s desktop computer only. It does not allow your application to share files with other applications on the same device. To share data and files between applications, use the pasteboard or a document interaction controller object.
For information on how to support file sharing in your application, see “Sharing Files with the User.”
The iTunes application automatically handles the backup and restoration of user data in appropriate situations. However, applications need to know where to put files in order to ensure that they are backed up and restored (or not) as the case may be.
You do not have to prepare your application in any way for backup and restore operations. In iOS 2.2 and later, when a device is plugged into a computer and synced, iTunes performs an incremental backup of all files, except for those in the following directories:
<Application_Home>/
AppName.app
<Application_Home>/Library/Caches
<Application_Home>/tmp
Although iTunes does back up the application bundle itself, it does not do this during every sync operation. Applications purchased from the App Store on the device are backed up when that device is next synced with iTunes. Applications are not backed up during subsequent sync operations though unless the application bundle itself has changed (because the application was updated, for example).
To prevent the syncing process from taking a long time, you should be selective about where you place files inside your application’s home directory. The <Application_Home>/Documents
directory should be used to store user documents and application data files. Files used to store temporary data should be placed inside the Application Home/tmp
directory and deleted by your application when they are no longer needed. If your application creates data files that can be used during subsequent launches, but which do not need to be backed up, it should place those files in the Application Home/Library/Caches
directory.
Note: If your application creates large data files, or files that change frequently, you should consider storing them in the Application Home/Library/Caches
directory and not in the <Application_Home>/Documents
directory. Backing up large data files can slow down the backup process significantly. The same is true for files that change regularly (and therefore must be backed up frequently). Placing these files in the Caches
directory prevents them from being backed up (in iOS 2.2 and later) during every sync operation.
For additional guidance about how you should use the directories in your application, see Table 1-1.
When a user downloads your application update, iTunes installs the update in a new application directory. It then moves the user’s data files from the old installation over to the new application directory before deleting the old installation. Files in the following directories are guaranteed to be preserved during the update process:
<Application_Home>/Documents
<Application_Home>/Library/Preferences
Although files in other user directories may also be moved over, you should not rely on their being present after an update.
The iPhone Simulator is a tool you can use to test your applications before deploying them to the App Store. The simulator provides a runtime environment that is close to, but not identical to, the one found on an actual device. Many of the restrictions that occur on devices, such as the lack of support for paging to disk, do not exist in the simulator. Also, some technologies such as OpenGL ES may not behave the same way in the simulator as they would on a device.
For more information about the simulator and its capabilities, see “Using iPhone Simulator” in iOS Development Guide.
Applications designed for iOS must be able to run on devices with different hardware features. Although features such as the accelerometers and Wi-Fi networking are available on all devices, some devices may not include a camera or GPS hardware. If your application requires such features, you should always notify the user of that fact before they purchase the application. For features that are not required, but which you might want to support when present, you must check to see if the feature is available before trying to use it.
Important: If a feature absolutely must be present in order for your application to run, configure the UIRequiredDeviceCapabilities
key in your application’s Info.plist
file accordingly. This key prevents users from installing applications that require features that are not present on a device. You should not include a key, however, if your application can function with or without the given feature. For more information about configuring this key, see “Declaring the Required Device Capabilities.”
Table 1-2 lists the techniques for determining if certain types of hardware are available. You should use these techniques in cases where your application can function without the feature but still uses it when present.
Feature | Options |
---|---|
To determine if multitasking is available… | Get the value of the |
To determine if you should configure your interface for an iPad-sized screen or an iPhone-sized screen… | Use the |
To determine if an external screen is attached… | Get the value of the |
To determine if hardware-level disk encryption is available… | Get the value of the |
To determine if the network is available… | Use the reachability interfaces of the System Configuration framework to determine the current network connectivity. For an example of how to use the System Configuration framework, see Reachability. |
To determine if the still camera is available… | Use the |
To determine if the device can capture video… | Use the |
To determine if audio input (a microphone) is available… | In iOS 3 and later, use the |
To determine if GPS hardware is present… | Specify a high accuracy level when configuring the |
To determine if a specific hardware accessory is available… | Use the classes of the External Accessory framework to find the appropriate accessory object and connect to it. For more information, see External Accessory Programming Topics. |
To get the current battery level of the device… | Use the |
To get the state of the proximity sensor… | Use the |
To obtain general information about device- or application-level features, use the methods and properties of the UIDevice
and UIApplication
classes. For more information about these classes, see UIDevice Class Reference and UIApplication Class Reference.
Last updated: 2010-06-30