Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Update Spotlight Search Index when working with Core Data?

I have an app that uses Core Spotlight to index the app content. The application also uses Core Data, and when creating a NSManagedObject the details of the object are used for the CSSearchableItem then added to the Spotlight Search Index.

The thing is I am under the impression that there is no direction reference to the NSManagedObject and the CSSearchableItem so when the item is added to the index it just copies the details.

Here is an example of adding an item to the index.

//Spotlight Index Search
// Create an attribute set to describe an item.

    let attributeSet = CSSearchableItemAttributeSet(itemContentType: kUTTypeData as String)

// Add metadata that supplies details about the item.

    attributeSet.title = "\(object.title)"
    attributeSet.contentDescription = "\(object.description)"

// Create an item with a unique identifier, a domain identifier, and the attribute set you created earlier.
    let item = CSSearchableItem(uniqueIdentifier: "1", domainIdentifier: "ObjectType", attributeSet: attributeSet)

// Add the item to the on-device index.
       CSSearchableIndex.defaultSearchableIndex().indexSearchableItems([item]) { error in

    if error != nil {
      print(error?.localizedDescription)
    }
      else {
      print("Item indexed.")
      }
    }

After adding the item to the index all items are searchable via spotlight search. A function in the appDelegate takes care of actions when selecting index items.

So everything seems fine until I edit or delete the NSManagedObject within the app, because the Searchable Items Index does not update the index the items listed in the index are not up to date and still list deleted/old data.

So how can I keep to CSSearchableIndex items updated when a NSManagedObject is updated ?

like image 772
RileyDev Avatar asked Dec 08 '15 20:12

RileyDev


3 Answers

Keeping index up to date is a critical if you want your index relevant. You have to add/remove items from index each time when you doing such operation with Core Data. You should use the following method to remove items from index before deleting from Core Data. Also you can find lots of useful info in CoreSpotlight docs.

- deleteSearchableItemsWithIdentifiers:completionHandler:

like image 53
Roman Kabachenko Avatar answered Oct 21 '22 14:10

Roman Kabachenko


You are on the right track, if you implement the willSave: method on your NSManagedObject, it will be invoked on any save/delete operation against that record. more on that here

https://developer.apple.com/library/mac/documentation/Cocoa/Reference/CoreDataFramework/Classes/NSManagedObject_Class/index.html#//apple_ref/occ/instm/NSManagedObject/willSave

Steps To Follow:

  1. Implement willSave method on your core data NSManagedObject Subclasses
  2. Lookup your indexed object that maps to the core data object
  3. Update/Delete that index

Tip: If you serialize your NSManagedObjectID for the core data object, (assuming you obtained the permanent ID for the object prior to saving it), you can use that to serve as the unique Identifier for your search index item so you can quickly find/update it

like image 22
Joseph Afework Avatar answered Oct 21 '22 13:10

Joseph Afework


You want the indexing to be in sync with the deletion of your items. Hence look for these three methods implemented by CSSearchableIndex class to delete items when they are no longer required.

  1. deleteAllSearchableItemsWithCompletionHandler(_:)
  2. deleteSearchableItemsWithDomainIdentifiers(_:completionHandler:)
  3. deleteSearchableItemsWithIdentifiers(_:completionHandler:)

Like this example,

CSSearchableIndex.defaultSearchableIndex().deleteSearchableItemsWithDomainIdentifiers(["tv-shows"]) { (error) -> Void in
    if error != nil {
        print(error?.localizedDescription)
    }
    else {
        // Items were deleted successfully
    }
}
like image 28
Kumar Utsav Avatar answered Oct 21 '22 14:10

Kumar Utsav