如何使用CSCus​​tomAttributeKey

时间:2018-07-26 15:33:00

标签: ios swift macos 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()
  }
}

在应用程序上初始化:

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开发人员论坛中发现了这个孤立的问题:

CSCustomAttributeKey valueForCustomKey not working

1 个答案:

答案 0 :(得分:0)

我认为这是iOS问题。 尽管它不是固定的,但也许Apple会允许您使用私有API来完成任务。

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

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

OR

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

这些词典中的键类型为NSString*CSCustomAttributeKey*,因此您可以尝试同时提供originalDataKeyNameoriginalDataKey