NSMetadataQuery未返回相关文件
我想用Spotlight来检索文件。它应该同时考虑文件名和文本内容。然而我得到的搜索结果与Finder中的结果或手动执行mdfind时的结果完全不同。下面的NSMetadataQuery只返回在浏览器缓存中匹配到的文件,而不是我主目录中的实际文件。问题出在哪里?
(附注:我已经通过entitlements禁用了应用沙箱。)
下面给出一个带固定搜索字符串的最小查询示例。
struct SpotlightSOExample: View {
@State private var results: [String] = []
@State private var query: NSMetadataQuery?
@State private var token: NSObjectProtocol?
var body: some View {
VStack(alignment: .leading, spacing: 8) {
List(results, id: \.self) { path in
Text(path)
}
}
.onAppear(perform: runSearch)
}
private func runSearch() {
results = []
let query = NSMetadataQuery()
query.searchScopes = [NSMetadataQueryUserHomeScope]
query.predicate = NSCompoundPredicate(orPredicateWithSubpredicates: [
NSPredicate(format: "kMDItemTextContent == %@", "*strom*"),
NSPredicate(format: "kMDItemDisplayName CONTAINS[cd] %@", "strom"),
])
query.valueListAttributes = [NSMetadataItemPathKey]
token = NotificationCenter.default.addObserver(
forName: .NSMetadataQueryDidFinishGathering,
object: query, queue: .main
) { [self] _ in
if let token { NotificationCenter.default.removeObserver(token) }
query.disableUpdates()
self.results = query.results.compactMap {
($0 as? NSMetadataItem)?.value(forAttribute: NSMetadataItemPathKey) as? String
}
query.stop()
self.query = nil
self.token = nil
}
query.start()
self.query = query
}
}
解决方案
这也让我很吃惊。我发现禁用应用沙箱是错误的。我知道这看起来有些违反直觉,但因为它们的特殊地位(在某种意义上,它们是“虚拟的”,因为它们“属于”iCloud Drive),桌面和文档是特殊的:NSMetadataQuery不会查询它们,除非应用沙箱处于启用状态。
完全不需要完整磁盘访问权限;你的说法在这点上是错的(这算是一个红鲱鱼)。只要开启沙箱,事情就会像你期望的那样工作。
站内所有文章版权归属LeftHeroAI导航站,无授权禁止任何主体转载、抄袭、复制内容,亦不得私自架设镜像站点。一经侵权,本站将通过法律途径追责。