我正在尝试从Core Spotlight取回一些数据,这些数据是使用自定义属性键存储的。也在macOS和iOS上进行了测试,结果始终是相同的。
我的考试班:
import CoreSpotlight
class SpotlightSearch {
let domainId = "com.company.some"
let originalDataKeyName: String
init() {
self.originalDataKeyName = domainId.replacingOccurrences(of: ".", with: "_") + "_originalData"
}
func addToIndex(title: String, content: String) {
guard let originalDataKey = CSCustomAttributeKey(keyName: originalDataKeyName, searchable: false, searchableByDefault: false, unique: false, multiValued: false)
else { return }
let uniqueId = "MyUniqueId" + title
let originalContent = NSString(string: content)
let attributeSet = CSSearchableItemAttributeSet(itemContentType: kUTTypeText as String)
attributeSet.title = title
attributeSet.setValue(originalContent, forCustomKey: originalDataKey)
let item = CSSearchableItem(uniqueIdentifier: uniqueId, domainIdentifier: domainId, attributeSet: attributeSet)
CSSearchableIndex.default().indexSearchableItems([item]) { error in
if let error = error {
print("Indexing error: \(error.localizedDescription)")
} else {
print("Item '\(title)' successfully indexed!")
}
}
}
var query: CSSearchQuery?
func search(title: String) {
var allItems = [CSSearchableItem]()
let queryString = "title == '\(title)'cd"
let attributes = [ "title", originalDataKeyName ]
let newQuery = CSSearchQuery(queryString: queryString, attributes: attributes)
newQuery.foundItemsHandler = { (items: [CSSearchableItem]) -> Void in
allItems.append(contentsOf: items)
}
newQuery.completionHandler = { [weak self] (error: Error?) -> Void in
guard let originalDataKeyName = self?.originalDataKeyName,
let originalDataKey = CSCustomAttributeKey(keyName: originalDataKeyName)
else { return }
print("Search complete")
for item in allItems {
let attributeSet = item.attributeSet
let customData = attributeSet.value(forCustomKey: originalDataKey)
// Always nil
if customData == nil {
print("\(String(describing: originalDataKeyName)) not found in \(attributeSet.description)")
} else if let originalData = customData as? NSData {
let data = Data(referencing: originalData)
if let originalString = String(data: data, encoding: .utf8) {
print("Found '\(originalString)'")
}
}
}
}
query = newQuery
newQuery.start()
}
}
在应用程序上初始化:
let newSpotlightSearch = SpotlightSearch()
newSpotlightSearch.addToIndex(title: "Banana", content: "")
稍后:
spotlightSearch.search(title: "Banana")
它将找到标题,但不会将自定义属性值还给我。如果我在“ // Always nil”之后放置一个断点并使用po attributeSet我将得到
(lldb) po attributeSet
{
"_kMDItemBundleID" = "de.axelspringer.SearchMac";
"_kMDItemDomainIdentifier" = "com.company.some";
"_kMDItemExpirationDate" = "2018-08-26 00:00:00 +0000";
"_kMDItemExternalID" = MyUniqueIdBanana;
"com_company_some_originalData" = "\Ud83c\Udf4c";
kMDItemTitle = Banana;
}
因此该值存在,但是Spotlight不会将其返回给我。自定义属性已经尝试使用NSData代替NSString,但是结果相同。
也在Apple开发人员论坛中发现了这个孤立的问题:
答案 0 :(得分:0)
我认为这是iOS问题。 尽管它不是固定的,但也许Apple会允许您使用私有API来完成任务。
因此,attributeSet
具有私有词典attributes
和customAttributes
。您可以尝试使用键值编码和ObjC获取这些值:
NSDictionary *attributes = [attributeSet valueForKey:@"attributes"];
id customData = attributes[originalDataKeyName];
OR
NSDictionary *customAttributes = [attributeSet valueForKey:@"customAttributes"];
id customData = customAttributes[originalDataKeyName];
这些词典中的键类型为NSString*
或CSCustomAttributeKey*
,因此您可以尝试同时提供originalDataKeyName
和originalDataKey
。