iOS 5 for developers – what you need to know
Wow Apple has added a TON of new features for developers in iOS 5. Make sure you read this article if you are an iPhone / iPad developer to get the skinny on what is coming. This article summarizes the key developer-related features introduced in iOS 5.0. This version of the operating system runs on current iOS-based devices. In addition to describing the key new features, this article lists the documents that describe those features in more detail.
iCloud Storage APIs
The iCloud storage APIs let your application write user documents and data to a central location and access those items from all of a user’s computers and iOS devices. Making a user’s documents ubiquitous using iCloud means that a user can view or edit those documents from any device without having to sync or transfer files explicitly. Storing documents in a user’s iCloud account also provides a layer of security for that user. Even if a user loses a device, the documents on that device are not lost if they are in iCloud storage.
There are two ways that applications can take advantage of iCloud storage, each of which has a different intended usage:
- iCloud document storage—Use this feature to store user documents and data in the user’s iCloud account.
- iCloud key-value data storage—Use this feature to share small amounts of data among instances of your application.
Most applications will use iCloud document storage to share documents from a user’s iCloud account. This is the feature that users think of when they think of iCloud storage. A user cares about whether documents are shared across devices and can see and manage those documents from a given device. In contrast, the iCloud key-value data store is not something a user would see. It is a way for your application to share very small amounts of data (tens of kilobytes) with other instances of itself. Applications can use this feature to store important state information. A magazine application might save the issue and page that the user read last, while a stocks application might store the stock symbols the user is tracking.
The summary for using the iCloud storage APIs in your application is as follows:
- Use the iOS Provisioning Portal to enable iCloud storage for your iOS application.Enabling this feature requires that you have an updated provisioning profile on your development systems. Xcode 4 handles this step for you automatically.
- Add an Entitlements file to your application and use it to configure the iCloud features your application uses
- Implement iCloud document storage as follows:
- Use the UIDocument class to read and write the contents of your user documents; alternatively, incorporate support for file presenters and file coordinators into the custom classes that you use to manage user documents. The iCloud service uses the file coordination mechanism to notify your application when a document changes. (The UIDocument class implements support for file presenters and file coordinators for you and is recommended.)
- Use the NSFileManager class to move the appropriate documents to the user’s iCloud storage. It is recommended that you give users the option to move documents to iCloud
- Use the NSMetadataQuery interfaces to search for documents in a user’s iCloud storage;
- Be prepared to handle version conflicts that might arise when two devices try to update a document at the same time;
The sections that follow provide more details about how to implement different aspects of iCloud storage for your application. For additional information about using specific classes and interfaces, see the corresponding reference documentation.
Storing and Using Documents in iCloud
Documents in iCloud provide the central location from which updates can be delivered to a user’s computers and iOS devices. All documents must be created in your application’s sandbox initially and moved to a user’s iCloud account later. A document targeted for iCloud storage is not moved to iCloud immediately, though. First, it is moved out of your application sandbox and into a local system-managed directory where it can be monitored by the iCloud service. After that transfer, the file is transfered to iCloud and to the user’s other devices as soon as possible.
While in iCloud storage, changes made on one device are stored locally and then pushed to iCloud using a local daemon, as shown in Figure 1. To prevent large numbers of conflicting changes from occurring at the same time, applications are expected to use file coordinator objects to perform all changes. File coordinators mediate changes between your application and the daemon that facilitates the transfer of the document to and from iCloud. In this way, the file coordinator acts like a locking mechanism for the document, preventing your application and the daemon from modifying the document simultaneously.
Figure 1 Pushing document changes to iCloud
From an implementation perspective, the easiest way to manage documents in iCloud is to use the UIDocument class. This class does most of the heavy lifting required to read and write files that are stored in iCloud. Specifically, the UIDocument class handles the creation and use of file coordinators to modify the document. This class also seamlessly integrates document changes coming from other devices. The class even helps handle the potential conflicts that can arise when two devices do manage to update the same file in conflicting ways. You are not required to use the UIDocument class to manage your application’s documents, but using it requires less effort on your part.
Important: Applications that store documents to iCloud must specify one or more containers in which to store those documents. You specify which containers your application supports using the com.apple.developer.ubiquity-container-identifiers entitlement.
The sections that follow discuss the basic mechanics of how you move documents to iCloud and manage them (with and without the help of theUIDocument class).
Moving a Document to iCloud Storage
To move a document to iCloud storage:
- Create and save the file locally in your application sandbox.
- If you are not using the UIDocument class to manage your file, create a file presenter to be responsible for it.
- Create an NSURL object that specifies the destination of the file in a user’s iCloud storage.You must put files in one of the container directories associated with your application. Call the URLForUbiquityContainerIdentifier:method of NSFileManager to get the root URL for the directory, and then append any additional directory and filenames to that URL. (Applications may put documents in any container directory for which they have the appropriate entitlement.
- Call the setUbiquitous:itemAtURL:destinationURL:error: method of NSFileManager to move the file to the specified destination in iCloud.
When moving documents to iCloud, you can create additional subdirectories inside the container directory to manage your files. It is strongly recommended that you create a Documents subdirectory and use that directory for storing user documents. In iCloud, the contents of theDocuments directory are made visible to the user so that individual documents can be deleted. Everything outside of the Documents directory is grouped together and treated as a single entity that a user can keep or delete. You create subdirectories in a user’s iCloud storage using the methods of the NSFileManager class just as you would any directory.
After you move a document to iCloud, it is not necessary to save a URL to the document’s location persistently. If you manage a document using a UIDocument object, that object automatically updates its local data structures with the document’s new URL. However, it does not save that URL to disk, and neither should your custom file presenters. Instead, because documents can move while in a user’s iCloud storage, you should use an NSMetadataQuery object to search for documents. Searching guarantees that your application has the correct URL for accessing the document.
Searching for Documents in iCloud
To locate documents in iCloud storage, your application must search using an NSMetadataQuery object. Searching is a guaranteed way to locate documents both in a user’s iCloud storage and in your application sandbox. You should always use query objects instead of saving URLs persistently because the user can delete files from iCloud storage when your application is not running. Using a query to search is the only way to ensure an accurate list of documents.
In iOS 5.0, the NSMetadataQuery class supports the following search scopes for your documents:
- Use the NSMetadataQueryUbiquitousDocumentsScope constant to search for documents in iCloud that reside somewhere inside aDocuments directory. (For any given container directory, put documents that the user is allowed to access inside a Documents subdirectory.)
- Use the NSMetadataQueryUbiquitousDataScope constant to search for documents in iCloud that reside anywhere other than in aDocuments directory. (For any given container directory, use this scope to store user-related data files that your application needs to share but that are not files you want the user to manipulate directly.)
- Use the NSMetadataQueryLocalDocumentsScope constant to search the Documents directory in your application’s sandbox.
To use a metadata query object to search for documents, create a new NSMetadataQuery object and do the following:
- Set the search scope of the query to an appropriate value (or values).
- Add a predicate to narrow the search results. To search for all files, specify a predicate with the format NSMetadataItemFSNameKey == *.
- Register for the query notifications and configure any other query parameters you care about, such as sort descriptors, notification intervals, and so on.The NSMetadataQuery object uses notifications to deliver query results. At a minimum, you should register for theNSMetadataQueryDidUpdateNotification notification, but you might want to register for others in order to detect the beginning and end of the results-gathering process.
- Call the startQuery method of the query object.
- Run the current run loop so that the query object can generate the results.If you started the query on your application’s main thread, simply return and let the main thread continue processing events. If you started the query on a secondary thread, you must configure and execute a run loop explicitly.
- Process the results in your notification-handler methods.When processing results, always disable updates first. Doing so prevents the query object from modifying the result list while you are using it. When you are done processing the results, reenable updates again to allow new updates to arrive.
- When you are ready to stop the search, call the stopQuery method of the query object.
Working with Documents in iCloud
When your application needs to read or write a document in iCloud, it must do so in a coordinated manner. Your application might not be the only application trying to manipulate the local file at any given moment. The daemon that transfers the document to and from iCloud also needs to manipulate it periodically. To prevent your application from interfering with the daemon (and vice versa), iOS provides a coordinated locking mechanism that works with the files and directories you target for iCloud storage.
At the heart of the iCloud locking mechanism are file coordinators and file presenters. Whenever you need to read and write a file, you do so using a file coordinator, which is an instance of the NSFileCoordinator class. The job of a file coordinator is to coordinate the reads and writes performed by your application and the sync daemon on the same document. For example, your application and the daemon may both read the document at the same time but only one may write to the file at any single time. Also, if one process is reading the document, the other process is prevented from writing to the document until the reader is finished.
In addition to coordinating operations, file coordinators also work with file presenters to notify applications when changes are about to occur. Afile presenter is any object that conforms to the NSFilePresenter protocol and takes responsibility for managing a specific file (or directory of files) in an application. The job of a file presenter is to protect the integrity of its own data structures. It does this by listening for messages from other file coordinators and using those messages to update its internal data structures. In most cases, a file presenter may not have to do anything. However, if a file coordinator declares that it is about to move a file to a new URL, the file presenter would need to replace its old URL with the new one provided to it by the file coordinator. The UIDocument class is an example of a file presenter that tracks changes to its underlying file or file package.
Here is a checklist of the things your application must do to work with documents in iCloud:
- Manage each document in iCloud using a file presenter. The recommended way to do this is to use the UIDocument class, but you may define custom file presenters if you prefer. You can use a single file presenter to manage a file package or a directory of files.
- After creating a file presenter, register it by calling the addFilePresenter: class method of NSFileCoordinator. Registration is essential. The system can notify only registered presenter objects.
- Before deleting a file presenter, unregister it by calling the removeFilePresenter: method of NSFileCoordinator.
All file-related operations must be performed through a file coordinator object. To read or write a document, or move or delete it, follow these steps:
- Create an instance of the NSFileCoordinator class and initialize it with the file presenter object that is about to perform the file operation.
- Use the methods of the NSFileCoordinatorobject to read or write the file:
- To read all or part of a single file, use the coordinateReadingItemAtURL:options:error:byAccessor: method
- To write to a file or delete it, call the coordinateWritingItemAtURL:options:error:byAccessor: method.
- To perform a sequence of read or write operations, use thecoordinateReadingItemAtURL:options:writingItemAtURL:options:error:byAccessor: method.
- To write to multiple files, or to move a file to a new location, use thecoordinateWritingItemAtURL:options:writingItemAtURL:options:error:byAccessor: method.
Handling File-Version Conflicts
When multiple instances of your application (running on different computers or iOS devices) try to modify the same document in iCloud, a conflict can occur. For example, if the devices are not connected to the network and the user makes changes on both, both devices try to push their changes to iCloud when they are reconnected to the network. At this point, iCloud has two different versions of the same file and has to decide what to do with them. Its solution is to make the most recently modified file the current file and to mark any other versions of the file as conflict versions.
Your application is notified of conflict versions through its file presenter objects. It is the job of the file presenter to decide how best to resolve any conflicts that arise. Applications are encouraged to resolve conflicts quietly whenever possible, either by merging the file contents or by discarding the older version if the older data is no longer relevant. However, if discarding or merging the file contents is impractical or might result in data loss, your application might need to prompt the user for help in choosing an appropriate course of action. For example, you might let the user choose which version of the file to keep, or you might offer to save the older version under a new name.
Applications should always attempt to resolve conflict versions as soon as possible. When conflict versions exist, all of the versions remain in a user’s iCloud storage (and locally on any computers and iOS devices) until your application resolves them. The current version of the file and any conflict versions are reported to your application using instances of the NSFileVersion class.
To resolve conflicts:
- Get the current file version using the currentVersionOfItemAtURL: class method of NSFileVersion.
- Get an array of conflict versions using the unresolvedConflictVersionsOfItemAtURL: class method of NSFileVersion.
- For each conflict version object, perform whatever actions are needed to resolve the conflict. Options include:
- Merging the conflict versions with the current file automatically, if it is practical to do so.
- Ignoring the conflict versions, if doing so does not result in any data loss.
- Prompting the user to select which version (current or conflict) to keep. This should always be your last option.
- If the current file version 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 contents of 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 the contents of the conflict version.
Storing Key-Value Data in iCloud
An application can use the NSUbiquitousKeyValueStore class to share small amounts of data with other instances of itself running on other computers and iOS devices. This class provides a similar service as the NSUserDefaults class in that it allows you to save simple data types (numbers, strings, dates, arrays, and so on) persistently and retrieve that data later. The main difference is that theNSUbiquitousKeyValueStore class writes that data to the user’s iCloud storage so that it can be retrieved by the application running on different iOS devices or computers.
Important: Applications that use the NSUbiquitousKeyValueStore class must also request the com.apple.developer.ubiquity-kvstore-identifierentitlement. If you configure multiple applications with the same value for this entitlement, all of them share the same key-value data. For more information about configuring iCloud entitlements, see “Requesting Entitlements for iCloud Storage.”
The amount of available space in a single key-value store is limited to 64 KB and the data for a single key cannot exceed 4 KB. Thus, you can use this storage to record small details about your application but should not use it to store user documents or other large data archives. Instead, you should use the information in the key-value store to improve the user experience for your application. For example, a magazine application might store the current issue and page number that the user is reading. That way, if the user opens the application on another device, the version of your application on that device can open to the same issue and page as the previous device.
The NSUbiquitousKeyValueStore class should not be used as a replacement or supplement for the NSUserDefaults class. An application should always write all of its configuration data to disk using the NSUserDefaults class. It should then write the data it intends to share to the key-value data store using the NSUbiquitousKeyValueStore class. This guarantees that your application always has a valid copy of the data available locally.
Requesting Entitlements for iCloud Storage
To protect the data each application creates, applications must request specific entitlements at build time in order to use iCloud storage. These entitlements are tied to the application’s provisioning profile and are used to differentiate your application’s documents and data from that of other applications.
There are two entitlements an application can request, depending on which iCloud features it uses:
- To use iCloud document storage, request the com.apple.developer.ubiquity-container-identifiers entitlement. The value of this key is an array of container identifier strings. (The first string in the array must not contain any wildcard characters.)
- To use the iCloud key-value data store, request the com.apple.developer.ubiquity-kvstore-identifier entitlement. The value of this key is a single container identifier string.
A container identifier string must be of the form <TEAM_ID>.<CUSTOM_STRING>, where <TEAM_ID> is the unique ten-character identifier associated with your developer account. The contents of <CUSTOM_STRING> are at your discretion, but it is recommended that you use a reverse-DNS string similar to your application’s bundle identifier. In practice, the string can be anything that makes sense to your development team. You can even use the same container identifier string for multiple applications if you want them to share the same storage space.
Applications using iCloud document storage can specify multiple containers for storing documents and data. The value of thecom.apple.developer.ubiquity-container-identifiers key is an array of strings. The first string in this array must be the main container identifier to associate with your application. If your company develops multiple applications, though, you can include additional container identifiers for your other applications. An application that supports multiple containers may read and write the documents and data in all of those containers, and searches always return a merged set of results.
Listing 1 shows the XML from an entitlements file that requests the keys for an iPad application. In this example, the iPad application can read and write its own documents (which it stores in the container directory identified using the A1B2C3D4E5.com.example.MyApp.ipad) and it can read and write files from the iPhone version of the same application (which may or may not use a different file format).
Listing 1 iCloud keys in the entitlements.plist file
Note: The strings you specify in your entitlements property-list file are also the strings you pass to theURLForUbiquityContainerIdentifier:method when requesting the location of a directory in the user’s iCloud storage.
Using iCloud Storage Responsibly
Applications that take advantage of iCloud storage features should act responsibly when storing data in there. The space available in each user’s account is limited and is shared by all applications. In addition, users can see how much space is consumed by a given application and choose to delete documents and data associated with your application. For these reasons, it is in your application’s interest to be responsible about what files you store. Here are some tips to help you manage documents appropriately:
- Rather than storing all documents, let a user choose which documents to store in an iCloud account. If a user creates a large number of documents, storing all of those documents in iCloud could overwhelm that user’s available space. Providing a way for a user to designate which documents to store in iCloud gives that user more flexibility in deciding how best to use the available space.
- Remember that deleting a document removes it from a user’s iCloud account and from all of that user’s computers and devices. Make sure that users are aware of this fact and confirm any delete operations. For your application to refresh the local copy of a document, use theevictUbiquitousItemAtURL:error: method of NSFileManager.
- When storing documents in iCloud, place them in a Documents directory 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 application in a user’s iCloud storage. A user’s iCloud account should be used only for storing user data and content that cannot be re-created by your application.
Users can now opt to have their applications and application data backed up directly to their iCloud account, making it easier to restore applications to their most recent state. Having data backed up in iCloud makes it easy for a user to reinstall that data to a new or existing iOS device. However, because the amount of space in a user’s iCloud account is limited, applications should be even more selective about where they store files.
The placement of files in your application’s home directory determines what gets backed up and what does not. Anything that would be backed up to a user’s computer is also backed up wirelessly to iCloud. Thus, everything in the Documents directory and most (but not all) of your application’s Library directory. To minimize the amount of data stored in the user’s iCloud account, developers are encouraged to put more files in the Library/Caches directory, especially if those files can be easily re-created or obtained in another way.
Note:Any documents that your application stores explicitly in iCloud (using the iCloud storage APIs) are not backed up with your application. (Those documents are already stored in the user’s iCloud account and therefore do not need to be backed up separately.) For information about how to store user documents in iCloud, see “Storing and Using Documents in iCloud.”
Automatic Reference Counting
Automatic Reference Counting (ARC) is a compiler-level feature that simplifies the process of managing the lifetimes of Objective-C objects. Instead of you having to remember when to retain or release an object, ARC evaluates the lifetime requirements of your objects and automatically inserts the appropriate method calls at compile time.
To be able to deliver these features, ARC imposes some restrictions—primarily enforcing some best practices and disallowing some other practices:
- Do not call the retain, release, autorelease, or dealloc methods in your code.In addition, you cannot implement custom retain or release methods.Because you do not call the release method, there is often no need to implement a custom dealloc method—the compiler synthesizes all that is required to relinquish ownership of instance variables. You can provide a custom implementation of dealloc if you need to manage other resources.
- Do not store object pointers in C structures.Store object pointers in other objects instead of in structures.
- Do not directly cast between object and nonobject types (for example, between id and void*).You must use special functions or casts that tell the compiler about an object’s lifetime. You use these to cast between Objective-C objects and Core Foundation objects.
- You cannot use NSAutoreleasePool objects.Instead, you must use a new @autoreleasepool keyword to mark the start of an autorelease block, and the @end keyword to mark the end of it.
ARC encourages you to think in terms of object graphs, and the relationships between objects, rather than in terms of retain and release. For this reason, ARC introduces new lifetime qualifiers for objects, including zeroing weak references. The value of a zeroing weak reference is automatically set to nil if the object to which it points is deallocated. There are qualifiers for variables, and new weak and strong declared property attributes, as illustrated in the following examples:
|// The following declaration is a synonym for: @property(retain) MyClass *myObject;|
|@property(strong) MyClass *myObject;|
|// The following declaration is similar to “@property(assign) MyOtherClass *delegate;”|
|// except that if the MyOtherClass instance is deallocated,|
|// the property value is set to nil instead of remaining as a dangling pointer|
|@property(weak) MyOtherClass *delegate;|
Xcode provides migration tools to help convert existing projects to use ARC.
Storyboards are the new way to define your application’s user interface. In the past, you used nib files to define your user interface one view controller at a time. A storyboard file captures your entire user interface in one place and lets you define both the individual view controllers and the transitions between those view controllers. As a result, storyboards capture the flow of your overall user interface in addition to the content you present.
If you are creating new applications, the Xcode templates come preconfigured to use storyboards. For other applications, the process for using storyboards is as follows:
- Configure your application’s Info.plistfile to use storyboards:
- Add the UIMainStoryboardFile key and set its value to the name of your storyboard file.
- Remove the existing NSMainNibFile key. (Storyboards replace the main nib file.)
Applications can use a single storyboard file to store all of their view controllers and views. At build time, Interface Builder takes the contents of the storyboard file and divides it up into discrete pieces that can be loaded individually for better performance. Your application never needs to manipulate these pieces directly, though. All you must do is declare the main storyboard in your application’s Info.plist file. UIKit handles the rest.
Creating Storyboard Files
You use Interface Builder to create storyboard files for your application. Most applications need only one storyboard file, but you can create multiple storyboard files if you want. Every storyboard file has a view controller known as the initial view controller. This view controller represents the entry point into the storyboard. For example, in your application’s main storyboard file, the initial view controller would be the first view controller presented by your application.
Each view controller in a storyboard file manages a single scene. For iPhone applications, a scene manages one screen’s worth of content, but for iPad applications the content from multiple scenes can be on screen simultaneously. To add new scenes to your storyboard file, drag a view controller from the library to the storyboard canvas. You can then add controls and views to the view controller’s view just as you would for a nib file. And as before, you can configure outlets and actions between your view controller and its views.
When you want to transition from one view controller to another, Control-click a button, table view cell, or other trigger object in one view controller, and drag to the view controller for a different scene. Dragging between view controllers creates a segue, which appears in Interface Builder as a configurable object. Segues support all of the same types of transitions available in UIKit, such as modal transitions and navigation transitions. You can also define custom transitions and transitions that replace one view controller with another.
Preparing to Transition to a New View Controller
Whenever a user triggers a segue in the current scene, the storyboard runtime calls the prepareForSegue:sender: method of the current view controller. This method gives the current view controller an opportunity to pass any needed data to the view controller that is about to be displayed. When implementing your view controller classes, you should override this method and use it to handle these transitions.
Presenting Storyboard View Controllers Programmatically
Although the storyboard runtime usually handles transitions between view controllers, you can also trigger segues programmatically from your code. You might do so when setting up the segue in Interface Builder is not possible, such as when using accelerometer events to trigger the transition. There are several options for transitioning to a new view controller:
- If a storyboard file contains an existing segue between the current view controller and the destination view controller (perhaps triggered by some other control in the view controller), you can trigger that segue programmatically using the performSegueWithIdentifier:sender:method of UIViewController.
- If there is no segue between the view controllers but the destination view controller is defined in the storyboard file, first load the view controller programmatically using the instantiateViewControllerWithIdentifier: method of UIStoryboard. Then present the view controller using any of the existing programmatic means, such as by pushing it on a navigation stack.
- If the destination view controller is not in the storyboard file, create it programmatically and present it as described in View Controller Programming Guide for iOS.
Newsstand provides a central place for users to read magazines and newspapers. Publishers who want to deliver their magazine and newspaper content through Newsstand can create their own iOS applications using the Newsstand Kit framework (NewsstandKit.framework), although doing so is not required. A big advantage of the Newsstand Kit framework, however, is that you can use it to initiate background downloads of new magazine and newspaper issues. After you start a download, the system handles the download operation and notifies your application when the new content is available.
Unlike other iOS applications, Newsstand applications appears only in Newsstand itself, not in a user’s Home screen. And instead of displaying an application icon, the application typically displays the cover of their most recent issue, with some additional adornments provided by Newsstand. When the user taps that cover art, your application launches normally to present the current issue or any back issues that were downloaded and are still available.
Note: Newsstand applications must include the UINewsstandApp key in their Info.plist file to indicate that they support Newsstand. For more information about this key, see Information Property List Key Reference.
Creating an application that uses Newsstand Kit requires some interplay between the actual application and the content servers that you manage. Your servers are responsible for notifying the application when new content is available, typically using a push notification. If your Newsstand application includes the UIBackgroundModes key with the newsstand-content value in its Info.plist file, your Newsstand application is launched in the background so that it can start downloading the latest issue. The download process itself is managed by the system, which notifies your application when the content is fully downloaded and available.
When your server is alerting your application of a new issue, that server should include the content-available property (with a value of 1) in the JSON payload. This property tells the system that it should launch your application so that it can begin downloading the new issue. Applications are launched and alerted to new issues once in a 24-hour period at most, although if your application is running when the notification arrives, it can begin downloading the content immediately.
In addition to your server providing content for each new issue, it should also provide cover art to present in Newsstand when that issue is available. This cover art is displayed in place of the application’s default icon, which is specified by the Newsstand-specific icons in theCFBundleIcons key of your application’s Info.plist file. Cover art gives users a more visual cue that a new issue is available. Your application can also add a badge to new issues.
AirPlay lets users stream audio and video from an iOS-based device to AirPlay–enabled devices such as televisions and audio systems. In iOS 5, developers can now use AirPlay to present application content on a nearby Apple TV 2. Users can now mirror the content of an iPad 2 to an Apple TV using AirPlay for any application. And developers who want to display different content (instead of mirroring) can assign a new window object to any UIScreen objects connected to an iPad 2 via AirPlay.
In addition, you can now take advantage of AirPlay in the following ways:
- Applications that use AV Foundation can now use the AVPlayer class to stream audio and video content over AirPlay; see AV Foundation Framework Reference.
- The Media Player framework includes support for displaying “Now Playing” information in several locations, including as part of the content delivered over AirPlay; see MPNowPlayingInfoCenter Class Reference.
- The UIWebView class now supports the presentation of multimedia content over AirPlay. This support is enabled by default, but you can opt out of it if you want to.
In iOS 5.0, there are several new frameworks you should investigate.
The GLKit framework (GLKit.framework) contains a set of Objective-C based utility classes that simplify the effort required to create an OpenGL ES 2.0 application. GLKit provides support for four key areas of application development:
- The GLKView and GLKViewController classes provide a standard implementation of an OpenGL ES–enabled view and associated rendering loop. The view manages the underlying framebuffer object on behalf of the application; your application just draws to it.
- The GLKTextureLoader class provides image conversion and loading routines to your application, allowing it to automatically load texture images into your context. It can load textures synchronously or asynchronously. When loading textures asynchronously, your application provides a completion handler block to be called when the texture is loaded into your context.
- The GLKit framework provides implementations of vector, matrix, and quaternions as well as a matrix stack operation to provides the same functionality found in OpenGL ES 1.1.
- The GLKBaseEffect, GLKSkyboxEffect, and GLKReflectionMapEffect classes provide precreated, configurable graphics shaders that implement commonly used graphics operations. In particular, the GLKBaseEffect class implements the lighting and material model found in the OpenGL ES 1.1 specification, simplifying the effort required to migrate an application from OpenGL ES 1.1 to OpenGL ES 2.0.
Core Image Framework
The Core Image framework (CoreImage.framework) provides a powerful set of built-in filters for manipulating video and still images. You can use the built-in filters for everything from simple operations (like touching up and correcting photos) to more advanced operations (like face and feature detection). The advantage of using these filters is that they operate in a nondestructive manner so that your original images are never changed directly. In addition, Core Image takes advantage of the available CPU and GPU processing power to ensure that operations are fast and efficient.
The CIImage class provides access to a standard set of filters that you can use to improve the quality of a photograph. To create other types of filters, you can create and configure a CIFilter object for the appropriate filter type.
The Twitter framework (Twitter.framework) provides support for sending Twitter requests on behalf of the user and for composing and sending tweets. For requests, the framework handles the user authentication part of the request for you and provides a template for creating the HTTP portion of the request. (Refer to the Twitter API for populating the content of the request.) The composition of tweets is accomplished using the TWTweetComposeViewController class, which is a view controller that you post with your proposed tweet content. This class gives the user a chance to edit or modify the tweet before sending it.
Users control whether an application is allowed to communicate with Twitter on their behalf using Settings. The Twitter framework also works in conjunction with the Accounts framework (Accounts.framework) to access the user’s account.
The Accounts framework (Accounts.framework) provides a single sign-on model for certain user accounts. Single sign-on improves the user experience, because applications no longer need to prompt a user separately for login information related to an account. It also simplifies the development model for you by managing the account authorization process for your application. In iOS 5.0, applications can use this framework in conjunction with the Twitter framework to access a user’s Twitter account.
Generic Security Services Framework
The Generic Security Services framework (GSS.framework) provides a standard set of security-related services to iOS applications. The basic interfaces of this framework are specified in IETF RFC 2743 and RFC 4401. In addition to offering the standard interfaces, iOS includes some additions for managing credentials that are not specified by the standard but that are required by many applications.
Application Design-Level Improvements
The following sections describe new capabilities that you can incorporate into the model, view, and controller layers of your application.
Cocoa Touch now includes a UIDocument class for managing the data associated with user documents. If you are implementing a document-based application, this class reduces the amount of work you must do to manage your document data. In addition to providing a container for all of your document-related data, the UIDocument class provides built-in support for a number of features:
- Asynchronous reading and writing of data on a background queue, allowing your application to remain responsive to users while reading and writing operations occur.
- Support for coordinated reading and writing of documents, which is required for documents in iCloud storage.
- Safe saving of document data by writing data first to a temporary file and then replacing the current document file with it.
- Support for resolving conflicts between different versions of your document if a conflict occurs.
- Automatic saving of document data at opportune moments.
- Support for flat file and package file representations on disk.
- For applications that use Core Data to manage their content, there is also a UIManagedDocument subclass to manage interactions with documents in the database.
If you are implementing an application that supports iCloud storage, the use of document objects makes the job of storing files in iCloud much easier. Document objects are file presenters and handle many of iCloud-related notifications that you might otherwise have to handle yourself.
Data Protection Improvements
Introduced in iOS 4.0, data protection lets you store application and user data files on disk in an encrypted format so that they can be accessed only when a user’s device is unlocked. In iOS 5.0, you now have more flexibility regarding when your application can access protected files.
- Using the NSFileProtectionCompleteUnlessOpen option, your application can access a file while the device is unlocked and, if you keep the file open, continue to access that file after the user locks the device.
- Using the NSFileProtectionCompleteUntilFirstUserAuthentication option, your application cannot access the file while the device is booting or until the user unlocks the device. After the user unlocks the device for the first time, you can access the file even if the user subsequently locks the device again.
You should protect files as soon as possible after creating them.
Custom Appearance for UIKit Controls
You can now customize the appearance of many UIKit views and controls to give your application a unique look and feel. For example, you might use these customizations to make the standard system controls match the branding for the rest of your application.
UIKit supports the following customizations:
- You can set the tint color, background image, and title position properties (among other) on a wide variety of objects, including toolbars, navigation bars, search bars, buttons, sliders, and some other controls.
- You can set attributes of some objects directly, or you can set the default attributes to use for a class using an appearance proxy.An appearance proxy is an object you use to modify the default appearance of visual objects such as views and bar items. Classes that adopt the UIAppearance protocol support the use of an appearance proxy. To modify the default appearance of such a class, retrieve its proxy object using the appearance class method and call the returned object’s methods to set new default values. A proxy object implements those methods and properties from its proxied class that are tagged with the UI_APPEARANCE_SELECTOR macro. For example, you can use a proxy object to change the default tint color (through the progressTintColor or trackTintColor properties) of the UIProgressViewclass.If you want to set a different default appearance based on how a given object is used in your application, you can do so using the proxy object returned by the appearanceWhenContainedIn:method instead. For example, you use this proxy object to set specific default values for a button only when it is contained inside a navigation bar.Any changes you make with a proxy object are applied, at view layout time, to all instances of the class that exist or that are subsequently created. However, you can still override the proxy defaults later using the methods and properties of a given instance.
Container View Controller Support
The UIViewController class now allows you to define your own custom container view controllers and present content in new and interesting ways. Examples of existing container view controllers include UINavigationController, UITabBarController, andUISplitViewController. These view controllers mix custom content with content provided by one or more separate view controller objects to create a unique presentation for application content. Container view controllers act as a parent for their contained view controllers, forwarding important messages about rotations and other relevant events to their children.
Applications that deliver custom preferences can now use a new radio group element. This element is similar to the multivalue element for selecting one item from a list of choices. The difference is that the radio group element displays its choices inline with your preferences instead of on a separate page.
The following sections describe the improvements to the Xcode tools and the support for developing iOS applications. For detailed information about the features available in Xcode 4.2, see Xcode New Features User Guide.
Xcode 4.2 adds support for many features that are available in iOS 5.0.
- The LLVM compiler supports Automatic Reference Counting (ARC), and Xcode includes a menu item to convert targets to use ARC. (For more information about ARC and about how to use it in your applications, see “Automatic Reference Counting.”)
- The Interface Builder user interface provides support for creating storyboard files for your iOS applications. (For more information about using storyboards in your iOS applications, see “Storyboards.”)
- In iOS Simulator, you can now simulate different locations for applications using the Core Location framework.
- You can download your application data from an iOS device and automatically restore that data when debugging or testing in iOS simulator or on a device.
OpenGL ES Debugging
The debugging experience in Xcode has been updated to include a new workflow for debugging OpenGL ES applications. You can now use Xcode to do the following for your OpenGL ES applications:
- Introspect OpenGL ES state information and objects such as view textures, shaders, and so on.
- Set breakpoints on OpenGL ES errors, set conditional OpenGL ES entry point breakpoints, break on frame boundaries, and so on.
UI Automation Enhancements
The Automation instrument now includes a script editor and the ability to capture (record) actions into your script as you perform them on a device. There are also enhancements to the objects that you use in the Automation instrument to automate UI testing:
- The UIATarget object can now simulate rotate gestures and location changes.
- The UIAHost object supports executing a task from the Instruments application itself.
- The UIAElement object can now simulate a rotate gesture centered on the element.
- Several functions that were previously available only in UIAWindow and UIAPopover were moved to UIAElement because they are common to all element objects.
- The UIAKeyboard object now supports performing a sequence of keyboard taps to simulate the typing of a string.
The Instruments application in Xcode 4.2 adds several new instruments for iOS developers:
- System Trace for iOS—Uses several instruments to profile aspects of Mac OS X or iOS that could be affecting application performance, such as system calls, thread scheduling, and VM operations.
- Network Connections instrument—Inspect how your application is using TCP/IP and UDP/IP connections. With this instrument it is possible to see how much data is flowing through each connection and for each application. You can also use it to display interesting statistics, such as round trip times and retransmission request information.
- Network Activity (located in Energy Diagnostics)—Helps bridge the gap between networking (cellular and WiFi) and energy usage. You use it to display device-wide data flow through each network interface alongside energy usage level data that is taken directly from the battery.
Additional Framework Enhancements
In addition to the items discussed in the preceding sections, the following frameworks have additional enhancements. For a complete list of new interfaces, see iOS 5.0 API Diffs.
The UIKit framework includes the following enhancements:
- The UIViewController class can now be used to create custom container view controllers; see “Container View Controller Support.”
- The UIKit framework provides support for loading and using storyboards; see “Storyboards.”
- Bars and bar button items can now be tinted and customized for your application; see “Custom Appearance for UIKit Controls.”
- The UIPageViewController class is a new container view controller for creating page-turn transitions between view controllers.
- The UIReferenceLibraryViewController class adds support for presenting a custom dictionary service to the user.
- The UIImagePickerController class supports new options for specifying the quality of video recordings.
- The UIStepper class is a new control for incrementing a floating-point value value up or down within a configurable range.
- View-based animations now support cross-dissolve, flip-from-top, and flip-from-bottom animations; see UIView Class Reference.
- The UIApplication class now reports the language directionality of the running application.
- The exclusiveTouch property of the UIControl class now defaults to YES instead of NO.
- The UITableView class adds support for automatic row animations, moving rows and sections, multiselection, and copy and paste behaviors for cells.
- The UIScreen class lets you specify overscan compensation behaviors for video delivered over AirPlay or through an attached HDMI cable. You can also programmatically set a screen’s brightness.
- The UIScrollView class now exposes its gesture recognizers so that you can configure them more precisely for your application.
- The UISegmentedControl class now supports proportional segment widths.
- The UIAlertView class now supports password-style text entry and special configurations for entering text securely.
- The UIColor class includes support for Core Image and new methods to retrieve individual color values.
- The UIImage class includes support for Core Image, support for stretching an image by tiling part of its content, and support for looping animations.
- The UITextInputTraits protocol adds support for a Twitter-specific keyboard and separate spell-checking behavior.
- The UIAccessibility protocol includes new interfaces that define the activation point within an element and indicate whether an element is modal or contains hidden elements. There are also new notifications that inform you of changes in system-provided accessibility features, such as zoom, audio status, and closed captioning.
- The UIAccessibilityReadingContent protocol allows you to provide a continuous, page-turning reading experience to VoiceOver users.
- The UIAccessibilityIdentification protocol allows you to uniquely identify elements in your app so that you can refer to them in automation scripts.
- The UIWebView class automatically supports the presentation of multimedia content over AirPlay. You can opt out of this behavior by changing the value in the mediaPlaybackAllowsAirPlay property of the class. This class also exposes a scrollView property so that you can access the scrolling properties of your web interfaces.
The OpenAL framework has two significant extensions:
- You can get notifications about source state changes and changes regarding the number of audio buffers that have been processed.
- The Apple Spatial Audio extension in iOS 5.0 adds three audio effects that are especially useful for games: reverberation, obstruction effects, and occlusion effects.
The Message UI framework adds a new notification for tracking changes to the device’s ability to send text messages.
The Media Player framework includes the following enhancements:
- There is now support for displaying “Now Playing” information in the lock screen and multitasking controls. This information can also be displayed on an Apple TV and with content delivered via AirPlay.
- You can detect whether video is being streamed to an AirPlay device using the airPlayVideoActive property of theMPMoviePlayerController class.
- Applications can now use the framework to play content from iTunes University.
The Map Kit framework supports the ability to use heading data to rotate a map based on the user’s current orientation. As you can with the Maps application, you can configure your map view to scroll the map according to the user’s current location. For example, a walking tour application might use this to show the user their current location on the tour.
For information on the interfaces you use to implement map scrolling and rotation, see Map Kit Framework Reference.
Note:If you are currently using Map Kit for geocoding, you should switch to using the Core Location framework for that feature; see “Core Location.”
The iAd framework provides new callback methods for developers who use multiple add networks and want to be notified when a new ad is available. The bannerViewWillLoadAd: method (defined in the ADBannerViewDelegate protocol) is called when a banner has confirmed that an ad is available but before the ad is fully downloaded and ready to be presented. The interstitialAdWillLoad: method (defined in theADInterstitialAdDelegate protocol) offers similar behavior for interstitial ads.
The Game Kit framework and Game Center now have the following features:
- The GKTurnBasedMatch class provides support for turn-based gaming, which allows games to create persistent matches whose state is stored in iCloud. Your game manages the state information for the match and determines which player must act to advance the state of the match.
- Your game can now adjust the default leaderboard (implemented by the GKLeaderboard class) shown to each player. If your game does not change the default leaderboard for a player, that player sees the leaderboard configured for your application in iTunes Connect.
- The GKNotificationBanner class implements a customizable banner similar to the banner shown to players when they log in to Game Center. Your game may use this banner to display messages to the player.
- When your game reports an achievement, it can automatically display a banner to the player using the GKAchievement class.
- A GKMatchmakerViewController object can now add players to an existing match in addition to creating a new match.
- The GKMatchDelegate protocol now includes a method to reconnect devices when a two-player match is disconnected.
The Foundation framework includes the following enhancements:
- The NSFileManager class includes new methods for moving a file to a user’s iCloud storage.
- The new NSFileCoordinator class and NSFilePresenter protocol implement now locking support and notifications when manipulating documents in iCloud.
- The new NSFileVersion class reports and manages conflicts between different versions of a file in iCloud.
- The NSURL class includes new methods and constants to support syncing items to a user’s iCloud storage.
- The new NSMetadataQuery class supports attributes for items synced to a user’s iCloud storage. Several other metadata-related classes were also added, including NSMetadataItem, NSMetadataQueryResultGroup, and NSMetadataQueryAttributeValueTuple.
- The new NSJSONSerialization class is a new class that supports back-and-forth conversions between JSON data and Foundation types.
- The new NSLinguisticTagger class is a new class lets you break down a sentence into its grammatical components, allowing the determination of nouns, verbs, adverbs, and so on. This tagging works fully for English and the class also provides a method to find out what capabilities are available for other languages.
- This framework now includes the NSFileWrapper class for managing file packages—that is, files implemented as an opaque directory.
- The new NSOrderedSet collection class offers the semantics of sets, whereby each element occurs at most once in the collection, but where elements are in a specific order.
- Most delegate methods are now declared using formal protocols instead of as categories on NSObject.
Event Kit and Event Kit UI
The Event Kit framework includes the following enhancements:
- The class hierarchy has been restructured. There is now a common base class called EKObject and portions of the EKEvent class have been moved into a new base class called EKCalendarItem.
- With the EKEventStore class, you can now create and delete calendars programmatically, fetch calendars based on their identifier, save and remove events in batches, and trigger a programmatic refresh of calendar data.
- The new EKSource class represents the source for creating new calendars and events.
- The EKCalendar class now provides access to a calendar’s UUID, source, and other attributes.
The Event Kit UI framework now includes the EKCalendarChooser class, which provides a standard way for selecting from the user’s iCal calendars.
The Core Motion framework now supports reporting heading information and magnetometer data for devices that have the corresponding hardware.
The Core Location framework (CoreLocation.framework) now includes support for both forward and reverse geocoding location data. This support allows you to convert back and forth between a set of map coordinates and information about the street, city, country (and so on) at that coordinate.
The Core Graphics framework (CoreGraphics.framework) includes some new interfaces to support the creation of paths. Specifically, there are new interfaces for creating paths with an ellipse or rectangle and for adding arcs to existing paths.
The Core Data framework includes the following enhancements:
- Core Data provides integration with the iOS document architecture and iCloud storage. The UIManagedDocument class is a concrete subclass of UIDocument that uses a Core Data persistent store for document data storage.
- For applications built for iOS 5.0 or later, persistent stores now store data by default in an encrypted format on disk. The default protection level prevents access to the data until after the user unlocks the device for the first time. You can change the protection level by assigning a custom value to the NSPersistentStoreFileProtectionKey key when configuring your persistent stores. For additional information about the data protection that are new in iOS 5.0, see “Data Protection Improvements.”
- Core Data formalizes the concurrency model for the NSManagedObjectContext class with new options. When you create a context, you can specify the concurrency pattern to use with it: thread confinement, a private dispatch queue, or the main dispatch queue. TheNSConfinementConcurrencyType option provides the same behavior that was present on versions of iOS prior to 5.0 and is the default. When sending messages to a context created with a queue association, you must use the performBlock: or performBlockAndWait:method if your code is not already executing on that queue (for the main queue type) or within the scope of a performBlock… invocation (for the private queue type). Within the blocks passed to those methods, you can use the methods of NSManagedObjectContext freely. TheperformBlockAndWait: method supports API reentrancy. The performBlock: method includes an autorelease pool and calls theprocessPendingChanges method upon completion.
- You can create nested managed object contexts, in which the parent object store of a context is another managed object context rather than the persistent store coordinator. This means that fetch and save operations are mediated by the parent context instead of by a coordinator. This pattern has a number of usage scenarios, including performing background operations on a second thread or queue and managing discardable edits, such as in an inspector window or viewNested contexts make it more important than ever that you adopt the “pass the baton” approach of accessing a context (by passing a context from one view controller to the next) rather than retrieving it directly from the application delegate.
- Managed objects support two significant new features: ordered relationships, and external storage for attribute values. If you specify that the value of a managed object attribute may be stored as an external record, Core Data heuristically decides on a per-value basis whether it should save the data directly in the database or store a URI to a separate file that it manages for you.
- There are two new classes, NSIncrementalStore and NSIncrementalStoreNode, that you can use to implement support for nonatomic persistent stores. The store does not have to be a relational database—for example, you could use a web service as the back end.
The Core Audio family of frameworks includes the following changes in iOS 5.0:
- Audio-session routing information is now specified using dictionary keys. There are also new modes for managing your application’s audio behavior:
- Voice chat mode optimizes the system for two-way voice conversation.
- Video recording mode configures the device for video capture.
- Measurement mode disables automatic compression and limiting for audio input.
- Default mode provides iOS 4.3.3 behavior.
- Core Audio adds seven new audio units for handling advanced audio processing features in your application, such as reverb, adjustable equalization, and time compression and stretching. The new Sampler unit lets you create music instruments, for which you can provide your own sounds. The new AUFilePlayer unit lets you play sound files and feed them directly to other audio units.
- The 3D Mixer audio unit is enhanced in iOS 5.0 to provide reverb and other effects useful in game audio.
- You can automate audio unit parameters in an audio processing graph, which lets you build a music mixer that remembers fader positions and changes.
- You can now use the advanced features of Apple Core Audio Format files in iOS. For example, you might create new voices for the Sampler audio unit.
- There is now programmatic support for adjusting the audio input gain.
- Core Audio now supports 32-bit floating-point audio data for applications that need to provide high quality audio.
The AV Foundation framework includes the following enhancements:
- There is automatic support for playing audio and video content over AirPlay. Applications can opt out of transmitting video over AirPlay using the allowsAirPlayVideo property of the AVPlayer class.
- New properties on the AVPlayerItem class indicate whether the item supports fast-forwarding or rewinding of the content.
The Assets Library framework includes the following enhancements:
- Support for accessing photo streams
- Support for creating new albums in the user’s photo library
- Support for adding assets to albums
- The ability to get an aspect ratio thumbnail for an asset
- The ability to modify saved assets
The Address Book framework adds support for importing and exporting vCard data. It also adds new keys to associate social network affiliations with a user record.
The Security framework (Security.framework) now includes the Secure Transport interfaces, which are Apple’s implementation of the SSL/TLS protocols. You can use these interfaces to configure and manage SSL sessions, manage ciphers, and manage certificates.