iOS NSCoreDataCoreSpotlightDelegate,如何重新索引所有项目
iOS NSCoreDataCoreSpotlightDelegate, how to reindex all items
我已经实现了 NSCoreDataCoreSpotlightDelegate,但我错过了默认到期日期为 1 个月的部分,现在我 3 个月前添加的项目没有显示在搜索索引中。
如何让 NSCoreDataCoreSpotlightDelegate 重新索引所有项目?
我以前可以这样称呼:
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: {})
第一次,它会重新索引所有项目,但如果我重新运行 应用程序再次取消注释上面的行,它不会重新索引。
如果我卸载应用程序,重新安装,然后取消注释上面的行,那么它会第一次重新索引所有内容。
如何让它重新索引所有内容?
这是因为 NSCoreDataCoreSpotlightDelegate 的实现使用 beginIndexBatch 和 endIndexBatchWithClientState 来重新索引 AllSearchableItems。所以它正在保存索引状态。当您调用 reindexAllSearchableItems 时,Spotlight 将检查状态并仅重新索引新项目。当您删除应用程序时,您也会删除索引状态。首先启动状态为空,NSCoreDataCoreSpotlightDelegate 索引所有项目。
为了您的目的,我认为设置过期日期比重新索引所有项目要好得多。您可以通过覆盖 attributeSet 在 MyCoreDataCoreSpotlightDelegate 上执行此操作:
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
}
要检查可搜索项目的到期日期,您可以使用 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()
}
}
像这样调用查询:
override func viewDidLoad() {
let query = QueryExample()
query.startQuery(withTitle: "S")
}
您应该会在控制台看到过期日期:
expirationDate:4001-01-01 00:00:00 +0000
我已经实现了 NSCoreDataCoreSpotlightDelegate,但我错过了默认到期日期为 1 个月的部分,现在我 3 个月前添加的项目没有显示在搜索索引中。
如何让 NSCoreDataCoreSpotlightDelegate 重新索引所有项目?
我以前可以这样称呼:
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: {})
第一次,它会重新索引所有项目,但如果我重新运行 应用程序再次取消注释上面的行,它不会重新索引。
如果我卸载应用程序,重新安装,然后取消注释上面的行,那么它会第一次重新索引所有内容。
如何让它重新索引所有内容?
这是因为 NSCoreDataCoreSpotlightDelegate 的实现使用 beginIndexBatch 和 endIndexBatchWithClientState 来重新索引 AllSearchableItems。所以它正在保存索引状态。当您调用 reindexAllSearchableItems 时,Spotlight 将检查状态并仅重新索引新项目。当您删除应用程序时,您也会删除索引状态。首先启动状态为空,NSCoreDataCoreSpotlightDelegate 索引所有项目。
为了您的目的,我认为设置过期日期比重新索引所有项目要好得多。您可以通过覆盖 attributeSet 在 MyCoreDataCoreSpotlightDelegate 上执行此操作:
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
}
要检查可搜索项目的到期日期,您可以使用 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()
}
}
像这样调用查询:
override func viewDidLoad() {
let query = QueryExample()
query.startQuery(withTitle: "S")
}
您应该会在控制台看到过期日期:
expirationDate:4001-01-01 00:00:00 +0000