iOS NSCoreDataCoreSpotlightDelegate,如何重新索引所有项目

标签 ios swift core-data corespotlight

我已经实现了 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 时,Spotlight 将检查状态并仅重新索引新项目。当您删除应用程序时,您也会删除索引状态。首次启动状态为空,NSCoreDataCoreSpotlightDelegate 为所有项目建立索引。

我认为为了您的目的,设置点过期日期而不是重新索引所有项目会更好。您可以在 MyCoreDataCoreSpotlightDelegate 中通过覆盖 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
}

要检查可搜索项目的过期日期,您可以使用 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

关于iOS NSCoreDataCoreSpotlightDelegate,如何重新索引所有项目,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55794439/

相关文章:

ios - 在 OpenGL 中绘制凹多边形

xcode - 核心数据错误: "Can' t find model for source store"

ios - 未根据给定的 EKRecurrenceRule 添加 EKEvent

ios - 出现弹出窗口时如何阻止选项卡栏项目变灰

ios - 使用 NodeJS 后端推送通知

swift - 在 Swift 中使用 NSTimer

iphone - 为什么 NSFetchedResultsController 没有用新数据更新?

iphone - 在 iPhone 上下载、保存和播放 mp3

ios - Google Cocoapods 未安装

swift - Comparable 协议(protocol)可以通用吗?