CSCustomAttributeKeys не могут быть доступны при извлечении уже проиндексированного CSSearchableItem - PullRequest
0 голосов
/ 08 июня 2019

Я пытаюсь использовать CoreSpotlight в приложении. Я уже настроил свои классы данных для создания CSSearchableItems, которые работают с Spotlight в iOS, но внутри приложения, из-за отображения, которое мы хотели бы использовать для результатов поиска, мне нужно больше информации для каждого результата. Я пытался создать CSCustomAttributeKeys, которые соответствуют информации, которая мне нужна, и они работают ... до некоторой степени. Я могу получить их до тех пор, пока они не войдут в индекс - тогда, когда я использую CSSearchQuery, чтобы вернуть их, они отформатированы по-разному и больше не могут быть доступны.

Я посмотрел на этот вопрос здесь: Как получить пользовательское значение из Spotlight с помощью CSCustomAttributeKey

Ответы подсказывают, что это ошибка iOS. Я надеюсь, что это было исправлено, но я не могу найти подтверждение.

Я также прочитал документацию несколько раз, но очень мало информации о том, как это настроить (если я что-то упустил).

Класс CSCustomAttributeKey определяет ключ, который вы можете связать с пользовательским атрибутом для элемента поиска. Атрибуты элемента обеспечивают метаданные об элементе, которые можно проиндексировать и отобразить пользователям в результаты поиска. Хотя платформа Core Spotlight предоставляет несколько предопределенные атрибуты, такие как заголовок и описание, вы можете создать CSCustomAttributeKey объект, чтобы указать пользовательский атрибут, который делает смысл в вашем домене.

Источник: https://developer.apple.com/documentation/corespotlight/cssearchableindex/1620333-indexsearchableitems?language=objc

Атрибуты, которые вы выбираете, зависят от вашего домена. Вы можете использовать свойства, которые Core Spotlight предоставляет в категориях, определенных на CSSearchableItemAttributeSet (например, Media and Documents), или вы можете определить свой собственный. Если вы хотите определить пользовательский атрибут, будьте как как можно более конкретно в вашем определении и использовать contentTypeTree свойство, чтобы ваш пользовательский атрибут мог наследоваться от известного типа.

Источник: https://developer.apple.com/documentation/corespotlight/cssearchableitemattributeset?language=objc

Я предполагаю, что наиболее важной строкой здесь является то, что мне нужно настроить contentTypeTree - однако я не понимаю цели или использования этого свойства:

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

...

Например, contentTypeTree для элемента, у которого contentType public.m3u-playlist должен включать public.m3u-playlist и public.playlist.

Источник: https://developer.apple.com/documentation/corespotlight/cssearchableitemattributeset/1621660-contenttypetree?language=objc

let attributeSet = CSSearchableItemAttributeSet(itemContentType: kUTTypeData as String)
attributeSet.title = title
attributeSet.contentDescription = description
attributeSet.keywords = keywords
attributeSet.setValue("5" as NSString, forCustomKey: "com_fake_test"!)

let item = CSSearchableItem(uniqueIdentifier: url, domainIdentifier: "com_fake", attributeSet: attributeSet)

// printing attributeSet here shows the custom attribute as separate from other attributes

CSSearchableIndex.default().indexSearchableItems([item]) { error in
            if let error = error {
                print("Indexing error: \(error.localizedDescription)")
            } else {
                print("Search item successfully indexed!")
            }
        }

// separate class, searchQuery is a global CSSearchQuery object and allItems is a global [CSSearchableItem] object
searchQuery?.cancel()

searchQuery = CSSearchQuery(queryString: spotlightQueryString(fromQueryString: curSearchStr!), attributes: ["com_fake_test"])

searchQuery?.foundItemsHandler = { (items: [CSSearchableItem]) in
    self.allItems.append(contentsOf: items)
}

searchQuery?.completionHandler = { (error) in
    guard error == nil else {
        print("Error: \(error?.localizedDescription)")
        return
    }
    DispatchQueue.main.async {
        for item in self.allItems {
             var attributes = item.attributeSet
             // this will be nil!
             var extractedAttribute = item.attributeSet.value(forCustomKey: IndexItemFactory.SUBSTANCE_ATTRIBUTE!)
        }
        self.searchComplete(SearchMultiResults(searchStr: self.curSearchStr!, substanceResults: substanceResults))
    }
}

searchQuery?.start()

Первая проверка атрибутов (до индексации):

"Printing description of attributes:
{
    "_kMDItemDomainIdentifier" = "come.fake.test";
    "_kMDItemExpirationDate" = "2019-07-08 00:00:00 +0000";
    "_kMDItemExternalID" = "fakeID";
    kMDItemContentType = "public.data";
    kMDItemDescription = "fake description";
    kMDItemKeywords =     (
        "keyword1",
        "keyword2",
        "keyword3"
    );
    kMDItemTitle = "fakeTitle";
}
Custom:
{
    "<CSCustomAttributeKey:0x6000024cfee0 com_fake_test" = 5;
}"

Повторная проверка атрибутов (после индексации):

"Printing description of attributes:
{
    "_kMDItemBundleID" = "com.fake";
    "_kMDItemDomainIdentifier" = "com.fake";
    "_kMDItemExpirationDate" = "2019-07-08 00:00:00 +0000";
    "_kMDItemExternalID" = "fakeID";
    "com_fake_test" = 5;
}"
...