Handoff is a capability introduced in iOS 8 and OS X v10.10 that transfers user activities among multiple devices associated with the same user. In iOS 9 and OS X v10.11, Handoff helps your app participate in search by making it possible to designate user activities and app states as searchable. For example, when a searchable activity or state appears in Spotlight search results or Siri suggestions, users can tap the result to return to the relevant area in your app.
Handoff lets users switch from one device to another and continue an ongoing activity seamlessly, without reconfiguring each device independently. For example, a user who is browsing a long article in Safari on a Mac can move to a nearby iOS device that’s signed into iCloud with the same Apple ID and open the same webpage automatically in Safari on iOS, at the same scroll position as on the original device.
Apple apps, such as Safari, Mail, Maps, Contacts, Notes, Calendar, and Reminders use public APIs to implement Handoff for iOS 8 and OS X v10.10. A third-party developer can use the same APIs to implement Handoff in apps that share the developer’s Team ID. Such apps must either be distributed through the App Store or signed by the registered developer.
Handing off a user activity involves three phases:
Create a user activity object for each activity the user engages in your app.
Update the user activity object regularly with information about what the user is doing.
Continue the user activity on a different device when the user requests it.
Document-based apps (that is, apps based on a subclass of
UIDocument), provide built-in support for all three phases of the handoff scenario. Responder objects (subclasses of
UIResponder) provide built-in support for updating user activities and managing their current status. Your app can also create, update, and continue user activities directly, working especially with the app delegate.
The Handoff mechanism depends primarily on objects of a single class in Foundation,
NSUserActivity, with support of additional small APIs in UIKit and AppKit. Apps encapsulate information about a user’s activities in
NSUserActivity objects, and those activities become candidates for continuation on other devices. Handoff of a given user activity requires the originating app to designate that activity’s
NSUserActivity object as the current activity, save pertinent data for continuation on another device, and send the data to the resuming device. Handoff passes only enough information between the devices to describe the activity itself, while larger-scale data synchronization is handled through iCloud.
On the continuing device, the user is notified that an activity is available for continuation. If the user chooses to continue the activity, an appropriate app is launched and provided with the activity’s payload data. A user activity can be continued only in an app that has the same developer Team ID as the activity's source app and that supports the activity's type. Supported activity types are specified in the app's
Info.plist under the
NSUserActivityTypes key (for more information about this key, see NSUserActivityTypes). So, the continuing device chooses the appropriate app based on the target Team ID, activity type property of the originating
NSUserActivity object, and optionally the activity object’s title property. From the information in the user activity object’s
userInfo dictionary, the continuing app can then configure its user interface and state appropriately for seamless continuation of the user’s activity.
Optionally, if continuing an activity requires more data than can be efficiently transferred by the initial transport mechanism, a resuming app can call back to the originating app’s activity object to open streams between the apps and transfer more data. For example, if the activity to be continued is composing an email message that contains an image, then the streams option is the best way to transfer the data needed to continue the composition on another device. For more information, see Using Continuation Streams.
Document-based apps on iOS and OS X automatically support Handoff, as described in Supporting a User Activity in Document-Based Apps.
User Activity Object
NSUserActivity object encapsulates the state of a user activity in an app on a particular device. It is the primary object in the Handoff mechanism and it helps you designate an activity or app state as searchable. The originating app creates a user activity object for each user activity that can be handed off to another device or that can appear in Spotlight search results. For example, a web browser would create a user activity object for each open tab or window in which the user is browsing URLs. However, only the activity object corresponding to the frontmost tab or window is current at a given time, and only the current activity is available for continuation.
NSUserActivity object is identified by its
title properties. In addition, you can use properties such as
contentAttributeSet to provide rich information about an activity to display in search results.
NSUserActivity class defines properties you use to specify the eligibility of an activity for various uses. For example, you can use
eligibleForSearch to add an activity to the on-device index and enable it to show up in the user’s search results and you can use
expirationDate to specify a date after which an activity is no longer eligible to be indexed or handed off.
NSUserActivity object also has a
userInfo dictionary to contain its state data and a flag named
needsSave that supports lazy updating of its state by its delegate. The
addUserInfoEntriesFromDictionary: enables the delegate and other clients to merge state data into its
For more information, see NSUserActivity Class Reference.
User Activity Delegate
The user activity delegate is an object that conforms to the
NSUserActivityDelegate protocol. It is typically a top-level object in the app, such as a view controller or the app delegate, that manages the activity’s interaction with the app.
The user activity delegate is represented by the
delegate property of
NSUserActivity and is responsible for keeping the data in the
NSUserActivity object’s user info dictionary up to date so that it can be handed off to another device. When the system needs the activity to be updated, such as before the activity is continued on another device, it calls the delegate’s
userActivityWillSave: method. You can implement this callback to make updates to the object’s data-bearing properties such as
title, and so on. Once the system calls this method, it resets
NO. Change this value to
YES if something happens that changes the
userInfo or other data-bearing properties again.
Alternatively, instead of implementing the delegate’s
userActivityWillSave: method, you can have UIKit or AppKit manage the user activity automatically. The app opts into this behavior by setting a responder object’s
userActivity property and implementing the responder’s
updateUserActivityState: callback, as described in Managing a User Activity With Responders. This arrangement is preferred if it works for your user activity.
For more information, see NSUserActivityDelegate Protocol Reference.
App Framework Support
UIKit and AppKit provide support for Handoff in the document, responder, and app delegate classes. Although there are minor behavioral differences between the platforms, the basic mechanism, which enables apps to save and restore user activities, is the same, and the APIs are the same.
Supporting a User Activity in Document-Based Apps
A document-based app on iOS and OS X automatically supports Handoff if you add an
NSUbiquitousDocumentUserActivityType key and value for each
CFBundleDocumentTypes entry in your app’s
Info.plist property list file. If this key is present,
UIDocument automatically create
NSUserActivity objects for iCloud-based documents of the given document type. The value of
NSUbiquitousDocumentUserActivityType is a string that represents the
NSUserActivity object’s activity type. That is, you provide an activity type for each document type supported by your document-based app. Multiple document types can have the same activity type.
UIDocument automatically put the value of their
fileURL property into the activity object’s
userInfo dictionary with the
In OS X, AppKit can automatically restore
NSUserActivity objects created in this way. It does so if the app delegate method
NO or is unimplemented. In this situation, the document is opened with the
openDocumentWithContentsOfURL:display:completionHandler: and receives a
For more information, see Adopting Handoff in Document-Based Apps. Also see NSDocument Class Reference and UIDocument Class Reference.
Managing a User Activity with Responders
UIKit and AppKit can manage a user activity if you set it as a responder object’s
userActivity property. When the responder knows that the activity state is dirty, it must set the object’s
needsSave property to
YES. The system automatically saves the
NSUserActivity object at appropriate times, first giving the responder an opportunity to update the activity’s state through the
updateUserActivityState: callback. Your responder subclass must override the
updateUserActivityState: method to add state data to the user activity object. If multiple responders share a single
NSUserActivity object, they all receive an
updateUserActivityState: callback when the system updates the user activity object. Before the update callbacks are sent, the activity object’s
userInfo dictionary is cleared.
In OS X,
NSUserActivity objects managed by AppKit and associated with responders automatically become current based on the main window and the responder chain, that is, when the document’s window becomes the main window. In iOS, however, for
NSUserActivity objects managed by UIKit, you must either call
becomeCurrent explicitly or have the document’s
NSUserActivity object set on a
UIViewController object that is in the view hierarchy when the app comes to the foreground.
A responder can set its
userActivity property to
nil to disassociate itself from an activity. When an
NSUserActivity object managed by the app framework has no more associated responders or documents, it is automatically invalidated.
For more information, see Adopting Handoff in Responders. Also see NSResponder Class Reference or UIResponder Class Reference.
Continuing an Activity Using the App Delegate
The app delegate is the primary entry point for continuing a user activity in a non-document-based app. As soon as the user chooses to resume an activity, either by responding to the notification or by selecting a search result, Handoff launches the appropriate app and sends the app’s delegate an
application:willContinueUserActivityWithType: message. The app lets the user know that the activity will continue shortly. Meanwhile, the
NSUserActivity object is delivered when the delegate receives an
application:continueUserActivity:restorationHandler: message. You should implement this method to configure your app in such a way that it can resume the activity represented by the user activity object.
application:continueUserActivity:restorationHandler: message includes a block, the restoration handler, that you can optionally call if your app uses auxiliary responder or document objects to perform the resuming user activity. Create these objects (or fetch them if cached) and pass them to the restoration handler in its
NSArray parameter. The system then sends each object a
restoreUserActivityState: message, passing the user activity object. Each object can use the activity’s
userInfo data to resume the activity. For more information about using this restoration handler, see the description of the
application:continueUserActivity:restorationHandler: method in NSApplicationDelegate Protocol Reference.
When you continue an activity that was chosen in a search result, you should regenerate the keywords for the activity, if appropriate, because the activity you receive may not have the same properties as the activity that was originally created.
If you do not implement
application:continueUserActivity:restorationHandler: or return
NO from it, and your app is document-based, AppKit can automatically resume the activity, as described in Supporting User Activity in Document-Based Apps. For more details, see Continuing an Activity.