Я пытаюсь использовать 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;
}"