iOS NSCoreDataCoreSpotlightDelegate, как переиндексировать все элементы - PullRequest
1 голос
/ 22 апреля 2019

Я реализовал NSCoreDataCoreSpotlightDelegate, и я пропустил ту часть, где expirationDate по умолчанию равен 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: {})

И в первый раз он будет переиндексировать все элементы, но если я перезапущуприложение с вышеуказанной строкой снова не закомментировано, оно не будет переиндексировать.

Если я удалю приложение, установите его обратно, а затем раскомментируйте указанную выше строку, тогда оно будет снова проиндексировано все в первый раз.

Как мне заставить его переиндексировать все заново?

1 Ответ

1 голос
/ 01 мая 2019

Это происходит потому, что реализация NSCoreDataCoreSpotlightDelegate использует beginIndexBatch и endIndexBatchWithClientState для reindexAllSearchableItems.Так что это сохранение состояния индекса.При вызове reindexAllSearchableItems Spotlight проверит состояние и переиндексирует только новые элементы.При удалении приложения вы также удаляете состояние индекса.При первом запуске состояние пустое и NSCoreDataCoreSpotlightDelegate индексирует все элементы.

Я думаю, что для вашей цели гораздо лучше установить expirationDate вместо переиндексации всех элементов.Вы можете сделать это в 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
}

Чтобы проверить expirationDate доступных для поиска элементов, вы можете использовать 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 на консоли:

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

...