The online home of John Pollard

Adding Entries In Spotlight Search

Surprisingly easy to do

I’ve had a bit of down time recently - which has been great - and in-between watching the Euros and the Tour de France, I’ve had time to watch quite a few WWDC videos.

One video entitled Showcase app data in Spotlight looked interesting, as I’d never considered adding anything from any of my apps into Spotlight Search.

Now the video itself wasn’t massively useful for me, as it was most about how you can feed Core Data easily into Spotlight - and I don’t really use Core Data unless I absolutely have to!

However, it inspired me to get the fixture and results data from my Yeltzland app into Spotlight.

Adding entries into Spotlight

The logic of my code is as follows:

  1. Listen for updates to the fixtures data
  2. On update, first remove all entries for the fixture data domain identifier (a unique string denoting the set of entries)
  3. Then add a new index entry for each match in the data set

The full code is available on GitHub and should be pretty self-explanatory.

To remove all entries for a domain identifer, simply call:

CSSearchableIndex.default().deleteSearchableItems(
    withDomainIdentifiers: [SpotlightManager.domainIdentifier],
    completionHandler: completionHandler)

Then the code to add an individual entry to the search index is straightforward too:

    var items: [CSSearchableItem] = []
    
    // Fetch all fixtures
    let fixtures = FixtureManager.shared.allMatches
    for fixture in fixtures {

        // Create an attribute set to describe the fixture
        let attributeSet = CSSearchableItemAttributeSet(itemContentType: kUTTypeData as String)
        attributeSet.title = fixture.spotlightSearchTitle
        attributeSet.contentDescription = fixture.spotlightSearchDescription
            
        // Create an item with a unique identifier, a domain identifier, and the attribute set you created earlier.
        let item = CSSearchableItem(uniqueIdentifier: "\(SpotlightManager.domainIdentifier)-\(fixture.identifier)",
                                    domainIdentifier: SpotlightManager.domainIdentifier,
                                    attributeSet: attributeSet)
        
        items.append(item)
    }
    
    CSSearchableIndex.default().indexSearchableItems(items) { error in
        if let error = error {
            print("Error add spotlight entries: ", error.localizedDescription)
        } else {
            print("Spotlight entries successfully added")
        }
    }

How it looks

That was all very simple, and you can see in the screenshot below it came out very nicely

Spotlight Example

If I’d have know it was that easy (and how to do it!), I would have added this years ago 😀