iOS NSCoreDataCoreSpotlightDelegate, how to reindex all items

时光毁灭记忆、已成空白 提交于 2019-12-23 04:13:36

问题


I have implemented NSCoreDataCoreSpotlightDelegate, and I missed out the part where the default expirationDate is 1 month, now items that I have added 3 months ago are not showing up in the search index.

How do I get NSCoreDataCoreSpotlightDelegate to reindex all the items?

I used to be able to call this:

let container = NSPersistentContainer(name: "MyApp")
let psd = NSPersistentStoreDescription(url:  FileManager.default.containerURL(forSecurityApplicationGroupIdentifier: "group.com.kiwlm.MyApp")!.appendingPathComponent("MyApp.sqlite"))

let mcdcsd = MyCoreDataCoreSpotlightDelegate(forStoreWith:psd, model: container.managedObjectModel)

container.persistentStoreDescriptions = [psd]

psd.setOption(mcdcsd, forKey:NSCoreDataCoreSpotlightExporter)

// uncomment the following to reindex all items
// mcdcsd.searchableIndex(CSSearchableIndex.default(), reindexAllSearchableItemsWithAcknowledgementHandler: {})

And the first time, it will reindex all the items, but if I re-run the app with the above line uncommented again, it will not reindex.

If I uninstall the app, install back, then uncomment the above line, then it will index all again for the first time.

How do I get it to reindex everything again?


回答1:


It happens because implementation of NSCoreDataCoreSpotlightDelegate use beginIndexBatch and endIndexBatchWithClientState to reindexAllSearchableItems. So it's saving index state. When you invoke reindexAllSearchableItems Spotlight will check the state and reindex only new items. When you delete the app you also delete index state. At first launch state is empty and NSCoreDataCoreSpotlightDelegate index all items.

I think for your purpose much better to set expirationDate instead of reindex all items. You can do it at MyCoreDataCoreSpotlightDelegate by override attributeSet:

override func attributeSet(for object: NSManagedObject) -> CSSearchableItemAttributeSet? {
    guard let attributeSet = super.attributeSet(for: object) else { return nil }
        if object.entity.name == "YourEntityName"  {
            // Setup necessary attributes
            attributeSet.setValue(Date.distantFuture, forKey: "expirationDate")
        }
    return attributeSet
}

To check expirationDate of searchable items you can use CSSearchQuery:

class QueryExample {
    var query : CSSearchQuery? = nil
    func startQuery(withTitle title : String) {
        var allItems = [CSSearchableItem]()
        // All the items that start with the specified title property using case insensitive comparison
        let queryString = "title == \"*\(title)*\"c"
        let attributes = ["title", "displayName", "keywords",
                      "contentType"]
        self.query = CSSearchQuery(queryString : queryString,
                               attributes : attributes)
        self.query?.foundItemsHandler = { (items : [CSSearchableItem])
        -> Void in
            allItems.append(contentsOf: items)
        }
        self.query?.completionHandler = { (error ) -> Void in
            for item in allItems {
                print("expirationDate:\(item.expirationDate)")
            }
        }
        self.query?.start()
    }
}

Invoke query like this:

   override func viewDidLoad() {
       let query = QueryExample()
       query.startQuery(withTitle: "S")
   }

And you should see expirationDate at console:

expirationDate:4001-01-01 00:00:00 +0000



来源:https://stackoverflow.com/questions/55794439/ios-nscoredatacorespotlightdelegate-how-to-reindex-all-items

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!