Update Spotlight Search Index when working with Core Data?
Asked Answered
L

3

13

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 ?

Limewater answered 8/12, 2015 at 20:38 Comment(0)
L
2

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
    }
}
Levorotatory answered 26/12, 2015 at 14:34 Comment(0)
F
6

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:

Fremont answered 21/12, 2015 at 15:44 Comment(0)
C
4

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

Crackling answered 25/12, 2015 at 21:22 Comment(1)
This seems the more pertinent answer to meLarimer
L
2

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
    }
}
Levorotatory answered 26/12, 2015 at 14:34 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.