【问题标题】:How can I access the text content (kMDItemTextContent) of an NSMetadataItem in Swift?如何在 Swift 中访问 NSMetadataItem 的文本内容 (kMDItemTextContent)?
【发布时间】:2019-09-26 09:56:36
【问题描述】:

我正在尝试使用 Swift 访问 NSMetadataQuery 结果的文本表示。但是,结果中不存在包含文件文本表示的属性kMDItemTextContent。我可以确认该属性应该存在,因为使用该属性搜索文件完美无缺。

到目前为止,这是我的代码:

import Foundation
import Cocoa

class Indexer {
    public let spotlight = NSMetadataQuery()
    let backgroundQueue = OperationQueue()

    init() {
        let nc = NotificationCenter.default

        spotlight.searchScopes = []
        spotlight.predicate = NSPredicate(fromMetadataQueryString: "kMDItemKind == *")

        nc.addObserver(forName: NSNotification.Name.NSMetadataQueryDidFinishGathering, object: nil, queue: self.backgroundQueue, using:{_ in
            self.spotlight.disableUpdates()
            for i in 0..<self.spotlight.resultCount {
                let result = self.spotlight.result(at: i) as! NSMetadataItem
                print("----- \(result.value(forAttribute: "kMDItemDisplayName") ?? "No title") -----")
                for attribute in result.attributes {
                    print("\(attribute):", result.value(forAttribute: attribute) ?? "No content")
                }
            }
            self.spotlight.enableUpdates()
        })

        spotlight.start()
    }
}

一个文件的当前结果如下所示:

----- n26-csv-transactions.csv -----
kMDItemContentTypeTree: (
    "public.comma-separated-values-text",
    "public.data",
    "public.delimited-values-text",
    "public.plain-text",
    "public.item",
    "public.content",
    "public.text"
)
kMDItemContentType: public.comma-separated-values-text
kMDItemPhysicalSize: 16384
kMDItemDisplayName: n26-csv-transactions.csv
kMDItemKind: CSV Document
kMDItemContentCreationDate: 2019-04-25 17:09:08 +0000
kMDItemContentCreationDate_Ranking: 2019-04-25 00:00:00 +0000
kMDItemContentModificationDate: 2019-04-25 17:09:08 +0000
kMDItemInterestingDate_Ranking: 2019-05-08 00:00:00 +0000
kMDItemUsedDates: (
    "2019-05-07 22:00:00 +0000"
)
kMDItemLastUsedDate: 2019-05-08 10:00:33 +0000
kMDItemLastUsedDate_Ranking: 2019-05-08 00:00:00 +0000
kMDItemUseCount: 3
kMDItemLogicalSize: 591
kMDItemWhereFroms: (
    "https://app.n26.com/download-csv",
    "https://app.n26.com/downloads"
)
kMDItemFSName: n26-csv-transactions.csv
kMDItemFSSize: 591
kMDItemFSCreationDate: 2019-04-25 17:09:08 +0000
kMDItemFSContentChangeDate: 2019-04-25 17:09:08 +0000
kMDItemFSOwnerUserID: 99
kMDItemFSOwnerGroupID: 99
kMDItemFSNodeCount: No content
kMDItemFSInvisible: 0
kMDItemFSTypeCode: 0
kMDItemFSCreatorCode: 0
kMDItemFSFinderFlags: 0
kMDItemFSHasCustomIcon: No content
kMDItemFSIsExtensionHidden: 0
kMDItemFSIsStationery: No content
kMDItemFSLabel: 0

这里似乎缺少kMDItemTextContent 属性。

有没有办法使用 Spotlight 返回的NSMetadataItems 访问该属性?如果没有,还有其他方法可以访问文件的文本表示形式吗?

【问题讨论】:

    标签: swift cocoa spotlight


    【解决方案1】:

    有没有办法使用 Spotlight 返回的 NSMetadataItems 访问该属性?如果没有,还有其他方法可以访问文件的文本表示形式吗?

    一句话:没有。阅读该属性上的docs

    包含文档内容的文本表示。多个字段中的数据应使用空白字符作为分隔符进行组合。应用程序的 Spotlight 导入器提供此属性的内容。 应用程序可以使用该属性创建查询,但不能直接读取该属性的值。 [强调我的。]

    文本内容信息进入 Spotlight 索引,因此,正如您所观察到的,您可以对其进行搜索。但是您无法以任何方式获得自己。它不以任何面向程序员的公共形式存在。

    (举个例子,现有的mdls 命令基本上就是你的代码所做的——你可以通过在进程中运行mdls 来省去麻烦。好吧,如果你给出一个mdls 命令终端,您不会在属性中看到kMDItemTextContent,即使此文件的内容已被索引。)

    要了解这是为什么,请考虑隐私。如果仅仅因为您可以访问 Spotlight,您就可以读取用户计算机上每个文件的文本表示,那么您就会知道用户计算机上的所有数据。除非您是某种邪恶的黑客,否则您甚至不应该这样做。要找出文件中的内容,请打开该文件——如果可以的话。

    那么这个属性到底是为了什么?这样您就可以通过自定义 Spotlight 导入器以属于您的文件类型提供文本 Spotlight。

    【讨论】:

    • 谢谢!我没有考虑隐私方面,这是有道理的。
    猜你喜欢
    • 1970-01-01
    • 2022-10-05
    • 2017-03-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-09-11
    • 1970-01-01
    • 2016-10-13
    相关资源
    最近更新 更多