Как я могу получить доступ к текстовому содержимому (kMDItemTextContent) NSMetadataItem в Swift? - PullRequest
0 голосов
/ 08 мая 2019

Я пытаюсь получить доступ к текстовому представлению результатов NSMetadataQuery, используя Swift. Однако атрибут 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 здесь отсутствует.

Есть ли способ получить доступ к этому атрибуту с помощью NSMetadataItem s, возвращаемых Spotlight? Если нет, есть ли другой способ получить доступ к текстовому представлению файла?

1 Ответ

2 голосов
/ 08 мая 2019

Есть ли способ получить доступ к этому атрибуту с помощью NSMetadataItems, возвращаемых Spotlight? Если нет, есть ли другой способ получить доступ к текстовому представлению файла?

Одним словом: нет. Прочитайте документы по этому атрибуту:

Содержит текстовое представление содержимого документа. Данные в нескольких полях должны объединяться с использованием символа пробела в качестве разделителя. Импортер Spotlight приложения предоставляет содержимое этого атрибута. Приложения могут создавать запросы с использованием этого атрибута, но не могут напрямую прочитать значение этого атрибута . [Акцент мой.]

Информация о текстовом содержимом попадает в указатель Spotlight, так что, как вы заметили, вы можете искать по нему. Но вы не можете получить это для себя каким-либо образом. Он не существует ни в какой общедоступной форме для программиста.

(Просто в качестве примера, существующая команда mdls делает в основном то, что делает ваш код - вы можете избавить себя от проблем, запустив mdls в Process. Хорошо, если вы дадите команду mdls в Терминал, вы не увидите kMDItemTextContent в списке атрибутов, даже если содержимое этого файла проиндексировано.)

Чтобы понять, почему это так, подумайте о конфиденциальности. Если бы вы могли прочитать текстовое представление каждого файла на компьютере пользователя только потому, что у вас есть доступ к Spotlight, вы бы знали все данные, которые есть на компьютере пользователя. Если вы не какой-то злой хакер, вы не должны этого хотеть. Чтобы узнать, что находится в файле, откройте файл - если можете.

Так для чего же этот атрибут? Это означает, что вы можете предоставить текст - Spotlight в типе файла, который принадлежит вам, с помощью пользовательского импортера Spotlight.

...