自定义Spotlight导入器和Finder的获取信息“更多信息”部分

时间:2013-05-03 07:52:51

标签: macos cocoa plugins metadata spotlight

我为我的应用程序定义的自定义文档类型编写了一个Spotlight Importer。

一切正常,Spotlight正确索引元数据字段(使用mdls命令验证),Spotlight搜索显示我的文档。

我遇到的唯一问题是,当我询问有关文件的信息时,我在<displayattrs>文件的schema.xml部分中指定的项目不会显示在“更多信息”部分中(Cmd +我在Finder中。)

我希望这些字段显示在那里,因为我在<allattrs><displayattrs>部分都声明了这些字段。

我在这里找到了几个与这个问题无关的问题,但没有一个问题对我有帮助。

导入器捆绑到应用程序中,由系统加载(mdimport -L已确认)。 此外,bundle结构似乎正确,schema.xml出现在Resources文件夹中,以及en / lproj文件夹中的schema.strings

以下是schema.xml文件的样子:

<schema version="1.0"
    xmlns="http://www.apple.com/metadata"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://www.apple.com/metadata file:///System/Library/Frameworks/CoreServices.framework/Frameworks/Metadata.framework/Resources/MetadataSchema.xsd">
<types>
    <type name="com.mydomain.myapp.mydocument">
        <allattrs>
            kMDItemTitle kMDItemAuthors kMDItemAlbum
        </allattrs>
        <displayattrs>
            kMDItemTitle kMDItemAuthors kMDItemAlbum
        </displayattrs>
    </type>
</types>

还有一些事情,我的系统缺少mdcheckschema命令,但是XML文件很短,我怀疑语法有问题。
有时,“更多信息”部分会显示文件的上次开放日期,有时甚至没有 最后,我尝试重新导入文件(mdimport),但无济于事。

我正在运行Mac OS X Moutain Lion 10.8.3,Xcode 4.6.2。

所以在这里我的问题是,我错过了在“更多信息”部分显示这些项目的内容吗? 是否有人遇到过这样的问题并找到了解决方案?

修改

到目前为止,没有人回答我的问题,也许有人可以指点我这个问题的教程或文档?

1 个答案:

答案 0 :(得分:10)

我知道文斯可能很久就解决了这个问题(或者放弃了)。但是,我花了很长时间来处理编写进口商的各种记录不完整或完全没有记录的问题,所以我想我会在这里记录我的发现。 (我担心这已成为一篇文章 - 这是一个复杂的主题)。

让我们假设:

  • 您已阅读documentation有关如何编写Spotlight导入程序的信息,特别是故障排除指南。
  • 您已编写并调试了导入程序。

    要在Xcode中调试导入器,请选择Product-&gt; Scheme-&gt; Edit Scheme并设置:

    • 信息 - &gt;可执行到/usr/bin/mdimport
    • 参数 - &gt; -n -d2 -g $(BUILT_PRODUCTS_DIR)/$(WRAPPER_NAME) /path/to/some/test/file.ext
    • 的参数
    • 选项 - &gt;工作目录至$(SRCROOT)

    并在GetMetadataForURL()函数上设置断点。

  • /usr/bin/mdimport -n -d2 -g /path/to/your/importer.mdimporter /path/to/some/test/file.ext的输出正确包含您想要的标准和/或自定义元数据属性。
  • 您已经部署了导入程序进行测试(在/ Library / Spotlight中独立/或嵌入在应用程序包中),mdimport -L列出了导入程序。
  • 但是mdls /some/other/file.ext和/或Finder的输出&#34;获取信息&#34;窗口不显示您期望的元数据属性。

这里有一些要检查的事情:

  1. 其他人需要为您要导入的文档类型声明UTI。

    • 如果您要导入system-declared类型的文档,那么OSX已经为您声明了UTI。
    • 如果您的导入程序嵌入在应用程序包中,则应用程序应通过应用程序的Info.plist中的UTExportedTypeDeclarations键声明UTI。
    • 如果您要导入第三方文档类型,请检查&#34;拥有的应用程序&#34;文档类型已在应用程序的Info.plist中的UTExportedTypeDeclarations键中声明了它的UTI。如果该应用尚未声明UTI(有些人不会使用旧的CFBundleDocumentTypes - > {> 1 {}},或者您希望自己的导入器工作即使应用程序尚未安装,您必须创建一个&#34;虚拟&#34;应用程序的唯一目的是在应用程序的Info.plist中的CFBundleTypeExtensions密钥中声明UTI。安装&#34;虚拟&#34;应用程序在/ Library / Application Support / myOrg / myApp.app。您的导入程序应该是独立的,不应嵌入此应用程序的捆绑包中,因为Spotlight无法从用户尚未打开的应用程序中运行导入程序。

    没有必要声明您导入的UTImportedTypeDeclarationsUTImportedTypeDeclarations个键中的UTI导入 Info.plist - LaunchServices无法从那里可靠地读取它们,因此Spotlight无法识别它们。但是,您必须在导入器信息的UTExportedTypeDeclarations - &gt; CFBundleDocumentTypes密钥中通过引用向UTI注册您对UTI的兴趣。 plist中。

    其他人没有正确声明UTI的症状是LSItemContentTypes说的:

    • mdimport -n -d1 /some/file.ext或(令人困惑):
    • Imported '/some/file.ext' of type 'dyn.xxx' ...

  2. 如果导入器返回的属性未在文档的UTI或任何父UTI的元数据架构中列出,则 Spotlight会抛弃该属性。即使它是像kMDItemAuthors这样的标准属性。要了解原因,我们需要详细了解Spotlight的工作原理:

    • 应用会在Imported '/some/file.ext' of type 'the.correct.uti' with no plugInUTImportedTypeDeclarations密钥中声明一个或多个UTI。
    • 在每个UTI声明中,该应用指定了一个或多个父母&#39; UTI位于UTExportedTypeDeclarations密钥中。如果可能,父UTI应该是特定的东西 - 例如&#34; public.image&#34;如果应用程序声明了一种新类型的图像文件 - 或只是&#34; public.data&#34;如果没有其他合适的话。

      • 您可以通过查看LaunchServices数据库的内容来查看UTI层次结构的当前状态:UTTypeConformsTo
      • 但这很难解读。幸运的是,您通常会对“清洁”的UTI层次结构更感兴趣。机器可以通过/System/Library/Frameworks/CoreServices.framework/Frameworks/LaunchServices.framework/Support/lsregister -dump获得。
    • Spotlight维护一个&#34;架构&#34;列出了它感兴趣的元数据属性:

      • 您可以使用plutil -p /System/Library/CoreServices/CoreTypes.bundle/Contents/Info.plist查看元数据架构的当前状态。
      • 您可以看到&#39; clean&#39;的元数据架构。机器在/System/Library/Frameworks/CoreServices.framework/Frameworks/Metadata.framework/Resources/schema.plist。
    • 当Spotlight决定存储内容时,它会针对UTI层次结构和元数据架构交叉引用导入器的输出。因此,对于导入器返回的每个属性:

      • Spotlight在元数据架构中查找文档的UTI。如果存在UTI条目,则Spotlight会检查导入程序返回的属性是否列在mdimport -X 2>&1项下。如果是,则Spotlight会记录导入程序在其数据库中提供的值。
      • 否则,Spotlight会在UTI层次结构中查找父UTI并重复该过程,直到它点击&#34; public.data&#34;。
      • 如果Spotlight无法找到文档的UTI的allattrs密钥中列出的属性,或者任何父UTI,则会丢弃导入器提供的值。

  3. 如果未列出Spotlight数据库中存储的属性,以便在文档的UTI或任何父UTI的元数据架构中显示,则 Finder && 39&s& #34;获取信息&#34;窗口不会显示。即使它是像kMDItemAuthors这样的标准属性。

    • Finder遵循与上述Spotlight类似的流程,但它会参考allattrs密钥而不是元数据库中的displayattrs密钥。
    • 显示属性的顺序取决于它们在元数据架构层次结构中的位置。

  4. 如果您想控制Spotlight存储的内容和/或Finder&#34;获取信息&#34;窗口显示然后您的导入器需要提供自定义架构。

    • 自定义schema.xml的格式已有详细记录。不幸的是,文档中提到的allattrs命令不再附带Xcode。如果你的机器有旧版本的OSX&amp;您可以从mdcheckschema复制Xcode。如果你有一个Apple Developer帐户,你可以从&#34; Xcode 4.2 for Snow Leopard&#34;中的/Packages/DeveloperToolsCLI.pkg中提取它。伤害。
    • 您不必在/usr/bin/mdcheckschemaallattrs键中列出导入器支持的每个属性 - 只列出未列出的属性对于/System/Library/Frameworks/CoreServices.framework/Frameworks/Metadata.framework/Resources/schema.plist中的父母或祖父母UTI。
    • 但是,如果您想控制订单,其中的属性会显示在&#34;获取信息&#34;在窗口中,您应该在displayattrs键中列出要按所需顺序首先显示的属性。 (例如参见&#34; public.movi​​e&#34;在架构中,它复制了其父级的一些键&#34; public.audiovisual-content&#34;以便它们首先显示)。
    • 您的架构必须displayattrs部分中定义至少一个自定义属性,并在attributes键中引用它,否则Spotlight会忽略整个架构。如果您的导入程序没有提供任何自定义属性,那么只需向模式添加虚假自定义属性。 (这个要求在Snow Leopard之后的某个时间到达并且完全没有记录,并且可能是Vince出错的地方。)
    • 如果您的架构定义了自定义属性(它应该;请参阅上一点),那么必须为其提供英语schema.strings本地化,否则Spotlight会忽略整个架构。 (当然,您也欢迎提供其他本地化)。
    • 检查您是否有&#34;复制捆绑资源&#34; Xcode项目中的阶段,将allattrsschema.xml复制到您的产品中。
    • 仔细检查您的内置中是否存在Contents / Resources / schema.xml和Contents / Resources / en.lproj / schema.strings或Contents / Resources / English.lproj / schema.strings 真的产品;一些旧版本的Xcode没有复制它们。
    • 检查schema.strings是否说:
      • file /path/to/your/built/importer.mdimporter/Contents/Resources/en.lproj/schema.strings

    出现上述任何错误的一个症状是Little-endian UTF-16 Unicode c program text不返回任何内容或返回导入程序的schema.xml尝试定义的UTI的空架构。

    < / LI>
  5. Spotlight并不总是及时发现变化。

    • 在测试导入程序的更新版本时,首先删除旧导入程序(如果它嵌入应用程序包中,则删除包含它的整个应用程序)并键入mdimport -X 2>&1 | grep -A20 uti.of.interest以检查Spotlight是否已注意到在部署更新版本之前,它已经消失了(这可能需要大约30秒)。再次输入mdimport -L以检查Spotlight是否已注意到更新后的版本(这可能需要约30秒)才能恢复测试。
    • 如果您要在.pkg文件中分发独立导入程序,那么您应该在1中包含一个postinstall脚本:告诉LaunchServices该捆绑包已更新(安装程序会自动为应用程序执行此操作,但不会对于其他捆绑类型)和2:使Spotlight重新为当前用户索引导入器理解的文档类型:

      mdimport -L

  6. LaunchServices并不总是及时发现变化,并保留旧信息。

    • 如果您正在对声明它们的应用程序中的UTI声明进行更改,或者对您的导入程序注册的UTI进行更改,则LaunchServices和Spotlight可能会混淆。您可以完全重置LaunchServices并使用以下命令从标准位置重新读取:

      #!/bin/sh touch -c "$2" if [ -n "$USER" ]; then sudo -u "$USER" /usr/bin/mdimport -r "$2"; fi true

      如果您想要模拟“清洁”,这也很有用。在您的开发系统上安装导入器和/或应用程序。

  7. 编辑:gitHub上的This project说明了上面的第1-5点。