Handling User Activity
Detect and respond to user activity information from Handoff or a complication.
Overview
SwiftUI provides the onContinueUserActivity(_:perform:) modifier to handle incoming NSUserActivity objects. This replaces the WatchKit extension delegate’s handle(_:) method.
For example, if you create a complication descriptor using the init(identifier:displayName:supportedFamilies:userActivity:) initializer to pass in an NSUserActivity object, when the user taps the corresponding complication, the system activates your app and passes the activity object to your onContinueUserActivity(_:perform:) modifiers. You can use the activity object to navigate to the corresponding content in your app.
// Create a list of the user's favorite cities.
List(favoriteCities) { city in
// Create a navigation link for each city.
// Activate the link if it is for the selected city.
NavigationLink(city.name,
destination: CityDetailView(city: city),
isActive: checkActive(city: city))
.onContinueUserActivity(viewCityFromComplication) { activity in
// App received a user activity object.
// Check to see whether it has a city index in the userInfo dictionary.
if let id = activity.userInfo?[cityIDKey] as? String {
// Navigate to the specified city.
selectedCity = allCities[id]
}
else {
// Display the favorite city list.
selectedCity = nil
}
}
}Note that in this example, selectedCity is a state variable that holds a City instance. The checkActive(city:) method creates a binding that indicates whether the given city is the currently selected city.
@State var selectedCity: City? = nil
// Returns a binding that determines whether a given
// city is the currently selected city.
func checkActive(city: City) -> Binding<Bool> {
Binding {
selectedCity == city
}
set: {
// If the binding is set to true, set the selected city
// to the provided city.
if $0 {
selectedCity = city
}
// if the binding is set to false,
// and the selected city is set to the provided city,
// clear the selected city.
else if selectedCity == city {
selectedCity = nil
}
}
}