Contents

Directing app intents to your app’s scenes

Direct app intents to a specific SwiftUI or UIKit scene and use the app intent to configure the content of the scene.

Overview

Some app intent protocols cause your app to come to the foreground so it can display action-specific details. For example, an app intent based on the OpenIntent protocol tells your app to display content for a specific data item or entity, and an app intent based on the ShowInAppSearchResultsIntent protocol tells your app to display the results of a search. Instead of making any interface-related changes from your app intent’s perform() method, a better approach is to make those changes from your scene code. To do that, you need the system to route relevant app intents to your app’s scenes, and you need to update your scene code to receive those app intents and update your views.

The system routes app intents to scenes with the help of the app intent’s target content identifier. This identifier is a custom string that you provide, although the framework also provides a default value you can use. In each of your scenes, you specify which target content identifiers the scene handles, and the system uses the information to match each app intent to the correct scene. After finding a matching scene, the system delivers the app intent to your custom code for handling.

Update your app intent to support scene-based routing

The system routes an app intent to one of your scenes only when the app intent implements the TargetContentProvidingIntent or UISceneAppIntent protocol. If you’re building scenes using SwiftUI, add the TargetContentProvidingIntent protocol to any app intents you want the system to direct to those scenes. If you’re building scenes using UIKit, add the UISceneAppIntent protocol to your app intents instead. Both protocols add a default implementation of the contentIdentifier property to your app intent, which provides the target content identifier the system needs to match your app intent to a scene. You can also add a custom implementation of the property to your app intent types if you want to supply a custom target content identifier for your type.

The following example shows an elided declaration of an app intent for a SwiftUI app that adopts the TargetContentProvidingIntent protocol. The app intent uses the default implementation of the contentIdentifier property, which contains the persistent identifier for the app intent type. App intents set this identifier to the app intent type name by default.

struct ShowBrowserAppIntent: AppIntent, TargetContentProvidingIntent {
    // ...
}

Match your app intent to a scene or view at runtime

When the system prepares to run an app intent, it checks to see if the app intent implements the TargetContentProvidingIntent or UISceneAppIntent protocol. If it does, the system examines the app’s scenes to determine if one of them wants to handle the app intent. If it finds a scene, the system dispatches the app intent to the scene before calling the app intent’s perform() method. Your scene code uses the app intent to configure its views to display the associated information. After that configuration, the system brings your app to the foreground to display the content.

When looking for a scene to handle an app intent, the system takes different approaches for SwiftUI and UIKit scenes. In your scene code, use the following techniques to tell the system which app intents your scene handles:

  • In SwiftUI scenes, specify which app intents your scene handles by adding the handlesExternalEvents(preferring:allowing:) modifier to one of the scene’s views. Configure the modifier with the target content identifiers your scene prefers to handle and can handle. If none of the scene’s views has this modifier, the system matches app intents using the handlesExternalEvents(matching:) modifier on the scene itself.

  • In UIKit scenes, specify which app intents your scene prefers, or can handle, using the scene’s activationConditions property, which you configure in the scene(_:willConnectTo:options:) method when preparing the scene.

The system compares the target content identifier of an incoming app intent to the values you provide in your SwiftUI modifiers or scene activation conditions. If you don’t provide a custom target content identifier for your app intent, you can use only the type of the app intent to choose which scene you want. However, if you provide a custom value, you can incorporate additional information to help with the routing process. For example, you might include the ID of a relevant entity in the app intent, so you can pick the scene already displaying the same entity. The following example shows an app intent that incorporates entity-specific information into its target content identifier.

struct ShowBrowserAppIntent: AppIntent, TargetContentProvidingIntent {
    @Parameter var item : ItemEntity
    
    var contentIdentifier: String { "ShowBrowser:\(item.id.uuidString)" }

    //...
}

To direct an app intent to a specific SwiftUI scene, add the handlesExternalEvents(preferring:allowing:) modifier to one of the scene’s views. The following example shows a view that displays an entity. Because the view already displays the entity, it prefers to handle incoming requests when the target content identifier contains the entity’s identifier. However, it also handles app intents that contain other entities.

struct BrowserView: View {
    @State private var item: ItemEntity
    
    init(item: ItemEntity) {
        self.item = item
    }
    
    var body: some View {
        VStack {
            Text("The item's name is: \(item.title)")
        }
        .padding()
        .handlesExternalEvents(preferring: (["ShowBrowser:" + item.id.uuidString]), allowing: ["*"])
    }
}

To configure the activation conditions in a UIKit scene, create predicates to match the target content identifiers of any incoming app intents. For an example of how to configure these activation conditions, see Supporting multiple windows on iPad.

Configure the contents of the scene

After determining which scene handles an app intent, the system dispatches the app intent to the scene so it can configure its views. The dispatching process happens in the background, giving the scene a chance to configure its views before any changes become visible. The scene configuration also happens before the system calls the app intent’s perform() method, giving you the opportunity to prepare your interface before the app intent does anything. For example, if the app intent plays a video, your scene needs to configure the views for the video before playback can start. To configure your scene:

In the implementation of your modifier or delegate method, extract data from the app intent and use it to configure the views in your scene. The following example retrieves the entity from the provided app intent and assigns it to the view. This behavior allows the view to update its content to display the content from the specified entity.

struct BrowserView: View {
    @State private var item: ItemEntity
    
    init(item: ItemEntity) {
        self.item = item
    }
    
    var body: some View {
        VStack {
            Text("The item's name is: \(item.title)")
        }
        .padding()
        .handlesExternalEvents(preferring: (["ShowBrowser:" + item.id.uuidString]), allowing: ["*"])
        .onAppIntentExecution(ShowSceneAppIntent.self) { intent in
            self.item = intent.item
        }
    }
}

The system provides an additional way to configure scenes in UIKit apps. If you don’t implement the scene(_:willPerformAppIntent:) method in your UIKit scene delegate, the system calls the performNavigation(forScene:) method of the app intent instead. If you have several app intents that change the scene in different ways, you might prefer this approach over a single delegate method that switches behavior based on the app intent type. The performNavigation(forScene:) method provides you with the scene to update, but you can also retrieve the scene from the uiScene property the UISceneAppIntent protocol adds to your type.

See Also

Scene support