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

Peg*_*lon 6 macos ios swift corespotlight

我试图从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()
  }
}
Run Code Online (Sandbox Code Playgroud)

在app init上:

let newSpotlightSearch = SpotlightSearch()
newSpotlightSearch.addToIndex(title: "Banana", content: "")
Run Code Online (Sandbox Code Playgroud)

后来:

spotlightSearch.search(title: "Banana")
Run Code Online (Sandbox Code Playgroud)

它会找到标题,但不会回复自定义属性值.如果我在"// 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;
}
Run Code Online (Sandbox Code Playgroud)

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

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

CSCus​​tomAttributeKey valueForCustomKey无效

Eug*_*nyk 1

我相信这是iOS的问题。虽然它还没有修复,但也许 Apple 会允许你使用私有 API 来完成你的任务。

因此,attributeSet有私人词典attributescustomAttributes. 您可以尝试使用键值编码和 ObjC 获取这些值:

NSDictionary *attributes = [attributeSet valueForKey:@"attributes"];
id customData = attributes[originalDataKeyName];
Run Code Online (Sandbox Code Playgroud)

或者

NSDictionary *customAttributes = [attributeSet valueForKey:@"customAttributes"];
id customData = customAttributes[originalDataKeyName];
Run Code Online (Sandbox Code Playgroud)

这些字典中的键类型是 或NSString*CSCustomAttributeKey*因此您可以尝试同时提供originalDataKeyNameoriginalDataKey