如何使用CSCus​​tomAttributeKey从Spotlight获取自定义值

时间:2022-09-10 19:18:12

I am trying to get some data back from Core Spotlight which I am storing using a custom attribute key. Tested this on macOS and iOS as well, the result is always the same.

我试图从Core Spotlight获取一些数据,我使用自定义属性键存储。在macOS和iOS上测试过,结果总是一样的。

My test class:

我的考试班:

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()
  }
}

On app init:

在app init上:

let newSpotlightSearch = SpotlightSearch()
newSpotlightSearch.addToIndex(title: "Banana", content: "????")

Later:

spotlightSearch.search(title: "Banana")

It will find the title, but will not give me back the custom attribute value. If I put a breakpoint after "// Always nil" and use po attributeSet I will get

它会找到标题,但不会回复自定义属性值。如果我在“// 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;
}

So the value is there, but Spotlight will not return it to me. Already tried to use NSData instead of NSString for the custom attribute, but same result.

所以价值就在那里,但Spotlight不会将它归还给我。已经尝试使用NSData而不是NSString作为自定义属性,但结果相同。

Also found this orphaned question in the Apple developer forums:

还在Apple开发者论坛中发现了这个孤立的问题:

CSCustomAttributeKey valueForCustomKey not working

CSCus​​tomAttributeKey valueForCustomKey无效

1 个解决方案

#1


0  

I believe it's iOS issue. While it's not fixed, maybe Apple will allow you to use a private API to do your thing.

我相信这是iOS问题。虽然它没有修复,但也许Apple会允许你使用私有API来做你的事情。

So, attributeSet has private Dictionaries attributes and customAttributes. You can try to get those values using Key Value Coding and ObjC:

因此,attributeSet具有私有Dictionaries属性和customAttributes。您可以尝试使用键值编码和ObjC获取这些值:

NSDictionary *attributes = [attributeSet valueForKey:@"attributes"];
id customData = attributes[originalDataKeyName];

OR

NSDictionary *customAttributes = [attributeSet valueForKey:@"customAttributes"];
id customData = customAttributes[originalDataKeyName];

Key type in those dictionaries is either NSString* or CSCustomAttributeKey*, so you can try supplying both originalDataKeyName and originalDataKey.

这些词典中的键类型是NSString *或CSCus​​tomAttributeKey *,因此您可以尝试同时提供originalDataKeyName和originalDataKey。

#1


0  

I believe it's iOS issue. While it's not fixed, maybe Apple will allow you to use a private API to do your thing.

我相信这是iOS问题。虽然它没有修复,但也许Apple会允许你使用私有API来做你的事情。

So, attributeSet has private Dictionaries attributes and customAttributes. You can try to get those values using Key Value Coding and ObjC:

因此,attributeSet具有私有Dictionaries属性和customAttributes。您可以尝试使用键值编码和ObjC获取这些值:

NSDictionary *attributes = [attributeSet valueForKey:@"attributes"];
id customData = attributes[originalDataKeyName];

OR

NSDictionary *customAttributes = [attributeSet valueForKey:@"customAttributes"];
id customData = customAttributes[originalDataKeyName];

Key type in those dictionaries is either NSString* or CSCustomAttributeKey*, so you can try supplying both originalDataKeyName and originalDataKey.

这些词典中的键类型是NSString *或CSCus​​tomAttributeKey *,因此您可以尝试同时提供originalDataKeyName和originalDataKey。