How can I open my app when an indexed entity is tapped in Spotlight?

Asked on 08/07/2024

1 search

To open your app when an indexed entity is tapped in Spotlight, you need to follow these steps:

  1. Conform to the IndexedEntity Protocol: First, ensure that your entity (e.g., a trail entity) conforms to the new IndexedEntity protocol. This allows your entity to be indexed by Spotlight.

  2. Index Your Entities: In your app's initialization method, index all the entities using CSSearchableIndex. This can be done by calling indexAppEntities on CSSearchableIndex.

  3. Implement an Intent: Create an intent that can handle the entity as a parameter. For example, an OpenTrailIntent that accepts a trail entity.

  4. Donate the Entity to Spotlight: Once your entities are indexed, they will appear in Spotlight search results. When a user taps on a search result, the associated intent will be triggered, opening your app to the relevant content.

Here is a brief example of how this can be implemented:

// Conform to IndexedEntity
struct Trail: IndexedEntity {
    var id: String
    var name: String
    // Other properties

    // Implement the required methods
    static var entityIdentifier: String {
        return "com.example.trail"
    }

    var displayRepresentation: DisplayRepresentation {
        return DisplayRepresentation(title: name)
    }

    var attributeSet: CSSearchableItemAttributeSet {
        let attributes = CSSearchableItemAttributeSet(itemContentType: kUTTypeItem as String)
        attributes.title = name
        // Add other attributes
        return attributes
    }
}

// Index the entities
func indexTrails() {
    let trails = dataManager.getAllTrails()
    CSSearchableIndex.default().indexAppEntities(trails)
}

// Create an intent
class OpenTrailIntent: INIntent {
    @NSManaged var trail: Trail?
}

// Donate the entity to Spotlight
func donateTrailToSpotlight(trail: Trail) {
    let intent = OpenTrailIntent()
    intent.trail = trail
    let interaction = INInteraction(intent: intent, response: nil)
    interaction.donate { error in
        if let error = error {
            print("Failed to donate interaction: \(error)")
        }
    }
}

For more detailed information, you can refer to the session What’s new in App Intents (02:35).

Relevant Sessions