- iOS 12.0+
- macOS 10.14+
- Xcode 10.1+
This sample app searches for Apple Store locations and shows them on a map. The user can choose a store’s map annotation to see its address and mark it as a favorite. As the user changes visible regions or inspects individual stores, the app uses Handoff to share these activities with the user’s other devices. If the user changes devices, they can use Handoff to launch the app and return to what they were doing on the original device.
The sample project builds for both macOS and iOS, so you can run it on a Mac, iPhone, and iPad. The project does not contain a watchOS or tvOS app.
Configure the Sample Code Project
Handoff must be run on actual devices; the iOS version cannot run in Simulator.
To configure your Mac to run the sample code project, open System Preferences and do the following:
In Bluetooth settings, click Turn Bluetooth On.
In iCloud settings, verify that you are signed into iCloud. If you are not, click Sign In and enter your Apple ID and password.
In General settings, select “Allow Handoff between this Mac and your iCloud devices”.
To configure your iOS devices to run the sample code project, open the Settings app and do the following:
In Bluetooth settings, tap to turn on Bluetooth.
In the user banner at the top of Settings, tap to sign in with your Apple ID if you haven’t already. Then tap to turn on iCloud.
In General settings, tap to turn on Handoff.
To configure the sample code project so that it can run on your devices, open the
Handoff project in Xcode and do the following:
Handoffproject at the top of the Project Navigator, select the
Handofftarget, select the “General” tab, and change the Bundle Identifier to a unique value, such as one that uses your organization’s name instead of
Map Viewer Mac
Handoffproject still selected in the Project Navigator, select the
Handofftarget, select the “General” tab, and change the Bundle Identifier to the same value you used in the previous step.
Map Viewer IOS
To run the macOS version, build the
Handofftarget, and run it locally, or copy the application file from the
Map Viewer Mac
Productsfolder to another Mac and run it there.
To run the iOS version, build the
Handofftarget and run it on one of your connected iOS devices.
Map Viewer IOS
Define User Activities
You implement Handoff by determining specific activities that a user can perform in your app, and whose state you can reproduce on a second device. The sample app has two user activities:
Viewing a map region.
Viewing the details of a specific Apple Store and editing its “favorite” value.
You use the app’s
Info to tell Handoff which activities your app can continue, by providing an entry with the key name
NSUser. The type of this entry is
Array, and each member is a
String representing a supported Handoff activity. In the sample app, the macOS and iOS targets include the
store-editing activites in their
Manage User Activities
At runtime, you represent a user activity with the
NSUser type. You initialize a user activity object with a string identifier, the same one used earlier in the
Info. This object also has an
is property that exposes the activity to Handoff, and a
user dictionary containing data needed to recreate the app’s state on the receiving device.
In the sample app, the
Map manages two
NSUser instances: one each for the
store-editing activities. When the map region changes, it sets the
user property (defined in
NSView for macOS and
UIView for iOS) to the
map-viewing activity. It makes this the current activity, replacing any other activity that may have previously been sent to Handoff, and sets
true, indicating that the activity has new data to send to remote devices.
needs on the view controller’s
user eventually results in a callback to the method
update, declared in
UIResponder on iOS and
NSResponder on macOS. This is the app’s opportunity to refresh the activity object’s
user before Handoff receives the activity. The implementation in the sample app calls a convenience function
update, defined in an extension on
NSUser, to encode the map view’s
MKCoordinate into key-value entries in the
Receive User Activities
When you move to another device, macOS or iOS indicates that a Handoff activity is available. macOS displays a Handoff icon at the beginning of the Dock, with a badge indicating the type of source device. On iOS, the Handoff banner appears at the bottom of the screen in the app switcher, showing the app and source device name.
When you launch the app using the Handoff prompts, the system calls methods in
UIApplication (iOS) or
NSApplication (macOS) to provide the Handoff activity. The
application(_: method provides the activity, along with a completion handler that you call with an array of view controllers that can handle the activity. The implementation in the iOS app delegate just finds and passes the first view controller, an instance of
The implementation in the macOS app delegate is similar, except that it traverses the key window’s hierarchy, rather than the iOS navigation controller stack:
Update the App’s State
The view controllers receive the
NSUser in the
Map inspects the activity to determine whether it is the map-viewing or the store-editing activity, and then updates the UI as needed. The map-viewing activity case resets the map region, by creating a new
MKCoordinate from the values in the
In the case of the store-editing activity, the view controller also retrieves the store’s URL and location coordinates from the
user. The app waits until the map adds a
MKAnnotation for the store being edited, so it knows where to anchor the popover.
Update the Original Device’s State (Optional)
NSUser class has a
delegate property of type
NSUser. This notifies the originating device when you continue an activity on another device. The originating device can use this to clean up its own UI state.
In the sample app, tapping a pin for an Apple Store shows a popover with details about the store and a switch (iOS) or checkbox (macOS) to mark the store as a favorite. The
Map represents this activity as the
store property, and sets itself as the activity’s delegate. When you continue editing on a second device, the delegate on the originating device receives a notification that this activity has been continued, and dismisses its own popover.