Search Your Question

Can you search your app content In spotlight (search bar)?

Ans : 

Using spotlight search, here we can find loan no 14356 in our application and redirect to view details page of this loan number.

Apple offers us many iOS features that can boost our apps visibility even when the user is not using it. For example, features like Spotlight, Today Widget, iMessage, Push Notifications, Siri and so on...

Spotlight is a super-powerful search feature in iOS that searches through the contents of your installed apps that support it.

If we want our app content to appear in Spotlight, we need to use the CoreSpotlight framework. For creating searchable content we will need to be familiar with:

  • CSSearchableItemAttributeSet - specifies the properties that you want to appear in Spotlight (i.e. title, contentDescription, thumbnail). 
  • CSSearchableItem - this class represents the search item. We can assign a unique identifier for referring the object, a domain to manage the items in groups and attributeSet where we pass the CSSearchableItemAttributeSet that we have created for this object. 
  • CSSearchableIndex - a class that is responsible for indexing the content on Spotlight. It requires an array of CSSearchableItem.
Let's understand through some coding :

We have array of favourite books : 

var favorites = [Int]()   ->   This array contains int id of favourite book.

To enable searching content, we have to add our favourite list in spotlight content like following :

First import ,
import CoreSpotlight 
import MobileCoreServices

When new item added to favourite, it should be also added using following custom function :

func index(item: Int) {
    let book = books[item]

    let attributeSet = CSSearchableItemAttributeSet(itemContentType: kUTTypeText as String)
    attributeSet.title = book[0]
    attributeSet.contentDescription = book[1]

    let item = CSSearchableItem(uniqueIdentifier: "\(item)", domainIdentifier: "com.iosiqabooks", attributeSet: attributeSet)
    CSSearchableIndex.default().indexSearchableItems([item]) { error in
        if let error = error {
            print("Indexing error: \(error.localizedDescription)")
        } else {
            print("Search item successfully indexed!")

Understanding above code :

Let's create CSSearchableItemAttributeSet object. This attribute set can store lots of information for search, including a title, description and image, as well as use-specific information such as dates (for events), camera focal length and flash setting (for photos), latitude and longitude (for places), and much more.

Regardless of what you choose, you wrap up the attribute set inside a CSSearchableItem object, which contains a unique identifier and a domain identifier. The former must identify the item absolutely uniquely inside your app, but the latter is a way to group items together. Grouping items is how you get to say "delete all indexed items from group X" if you choose to, but in our case we'll just use "com.iosiqaswift" because we don't need grouping. As for the unique identifier, we can use the project number.

To index an item, you need to call indexSearchableItems() on the default searchable index of CSSearchableIndex, passing in an array of CSSearchableItem objects. This method runs asynchronously, so we're going to use a trailing closure to be told whether the indexing was successful or not.

By default, search item expiry of 1 month. After 1 month, it is deleted from spotlight. We can manually set expiration date like :

item.expirationDate = Date.distantFuture : It will never expire.

If we want to remove content from spotlight or to disable search item for spotlight,

func deindex(item: Int) {
    CSSearchableIndex.default().deleteSearchableItems(withIdentifiers: ["\(item)"]) { error in
        if let error = error {
            print("Deindexing error: \(error.localizedDescription)")
        } else {
            print("Search item successfully removed!")


We can now code for tapping on search result interaction in app delegate :

import CoreSpotlight in AppDelegate.swift.

We have to add following AppDelegate method :

func application(_ application: UIApplication, continue userActivity: NSUserActivity, restorationHandler: @escaping ([UIUserActivityRestoring]?) -> Void) -> Bool {
    if userActivity.activityType == CSSearchableItemActionType {
        if let uniqueIdentifier = userActivity.userInfo?[CSSearchableItemActivityIdentifier] as? String {
            if let navigationController = window?.rootViewController as? UINavigationController {
                if let viewController = navigationController.topViewController as? ViewController {

    return true

Credit : HackingWithSwift

No comments:

Post a Comment