macos - 自定义Spotlight导入器和查找器的“更多信息”部分

标签 macos cocoa plugins metadata spotlight

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

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

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

我希望这些字段出现在这里,因为我在<allattrs><displayattrs>部分中都声明了它们。

我在这里发现的几个与此问题有关的问题,没有一个对我有帮助。

导入程序捆绑到应用程序中,由系统加载(mdimport -L确认了这一点)。
另外,捆绑软件的结构似乎正确,schema.xml出现在Resources文件夹中,而schema.strings出现在en / lproj文件夹中。

这是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。

因此,这是我的问题,我是否缺少在“更多信息”部分中显示这些项目的内容?
是否有人遇到了这样的问题并找到了解决方案?

编辑:

到目前为止,没有人回答我的问题,也许有人可以给我指出有关此问题的一些教程或文档?

最佳答案

我知道文斯可能已经解决了很久(或放弃了)。但是我花了令人沮丧的很长时间来解决编写进口商的各种文献不充分或完全未记录的问题,所以我想我应该在这里记录我的发现。 (恐怕这变成了一篇论文-这是一个复杂的主题)。

假设:


您已阅读documentation有关如何编写Spotlight导入程序的信息,尤其是疑难解答指南。
您已经编写并调试了导入程序。

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


信息->可执行至/usr/bin/mdimport
参数-> -n -d2 -g $(BUILT_PRODUCTS_DIR)/$(WRAPPER_NAME) /path/to/some/test/file.ext的参数
选项->工作目录到$(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的“获取信息”窗口的输出未显示您期望的元数据属性。


这里有一些要检查的东西:


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


如果要导入system-declared类型的文档,则OSX已为您声明了UTI。
如果您的进口商嵌入在应用程序捆绑包中,则该应用程序应通过该应用程序的Info.plist中的UTExportedTypeDeclarations键声明UTI。
如果要导入第三方文档类型,请检查“拥有”该文档类型的应用程序是否已在其Info.plist的UTExportedTypeDeclarations键中为其声明了UTI。如果该应用程序尚未声明UTI(某些应用程序未声明,但仍使用旧的CFBundleDocumentTypes-> CFBundleTypeExtensions键),或者即使未安装该应用程序也希望导入程序正常工作,则您将拥有创建一个“虚拟”应用程序,其唯一目的是在应用程序的Info.plist的UTImportedTypeDeclarations键中声明UTI。将“虚拟”应用程序安装在/ Library / Application Support / myOrg / myApp.app之类的位置。您的导入程序应该是独立的,并且不应嵌入此应用程序的捆绑包中,因为Spotlight不会从用户尚未打开的应用程序中运行导入程序。


在进口商的Info.plist中的UTImportedTypeDeclarationsUTExportedTypeDeclarations键中声明要导入的UTI是没有意义的-LaunchServices无法从那里可靠地读取它们,因此Spotlight无法识别它们。但是,您必须通过在进口商的Info.plist中的CFBundleDocumentTypes-> LSItemContentTypes键中引用UTI来注册您对UTI的兴趣。

mdimport -n -d1 /some/file.ext表示其他人未正确声明UTI的症状是:


Imported '/some/file.ext' of type 'dyn.xxx' ...或(令人困惑):
Imported '/some/file.ext' of type 'the.correct.uti' with no plugIn



如果您的进口商返回的属性未在文档的UTI或任何父UTI的元数据架构中列出,则Spotlight会将其丢弃。即使它是kMDItemAuthors之类的标准属性。要了解原因,我们需要详细研究Spotlight的工作原理:


应用程序在UTImportedTypeDeclarationsUTExportedTypeDeclarations密钥中声明一个或多个UTI。
在每个UTI声明中,应用程序在UTTypeConformsTo密钥中指定一个或多个“父” UTI。如果可能的话,父UTI应该是特定的东西-例如如果应用声明一种新型图像文件,则为“ public.image”;如果没有其他合适的方法,则为“ public.data”。


您可以通过遍历LaunchServices数据库的内容来查看UTI层次结构的当前状态:/System/Library/Frameworks/CoreServices.framework/Frameworks/LaunchServices.framework/Support/lsregister -dump
但这很难破解。幸运的是,您通常会对机器的“干净”机器的UTI层次结构更加感兴趣。

Spotlight维护一个“模式”,其中列出了它感兴趣的元数据属性:


您可以使用plutil -p /System/Library/CoreServices/CoreTypes.bundle/Contents/Info.plist查看元数据架构的当前状态。
您可以在/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并重复该过程,直到其到达“ public.data”为止。
如果Spotlight找不到文档的UTI或任何父UTI的allattrs键中列出的属性,则它将丢弃导入程序提供的值。




如果未列出存储在Spotlight数据库中的属性以在文档的UTI或任何父UTI的元数据架构中显示,则Finder的“获取信息”窗口将不会显示该属性。即使它是kMDItemAuthors之类的标准属性。


Finder遵循与上述Spotlight相似的过程,除了它查询元数据数据库中的allattrs键而不是displayattrs键。
属性的显示顺序取决于它们在元数据架构层次结构中的位置。



如果要控制Spotlight存储的内容和/或Finder的“获取信息”窗口显示的内容,则导入程序需要提供自定义架构。


自定义schema.xml的格式已被详细记录。不幸的是,文档中提到的allattrs命令不再与Xcode一起提供。如果您有一台装有旧版OSX和Xcode的计算机,则可以从mdcheckschema复制它。如果您有Apple Developer帐户,则可以从/Packages/DeveloperToolsCLI.pkg中的“ Snow Leopard的Xcode 4.2” dmg中提取它。
您不必在/usr/bin/mdcheckschemaallattrs键中列出导入程序支持的每个属性-只需在/System/Library/Frameworks/CoreServices.framework/中为父母或祖父母UTI未列出的那些属性即可。 Frameworks / Metadata.framework / Resources / schema.plist。
但是,如果要控制属性在“获取信息”窗口中的显示顺序,则应在displayattrs键中按所需顺序列出要首先显示的属性。 (例如,参见架构中的“ public.movi​​e”,该方案复制了其父级“ public.audiovisual-content”中的某些键,以便首先显示它们)。
您的架构必须在displayattrs部分中定义至少一个自定义属性,并在attributes键中对其进行引用,否则Spotlight会忽略整个架构。如果您的进口商不提供任何自定义属性,则无论如何都只需将伪造的自定义属性添加到架构中。 (此要求在Snow Leopard之后的某个时间到达,并且完全没有记录,并且可能是Vince出问题的地方)。
如果您的架构定义了一个自定义属性(并且应该;请参见上一点),则必须为其提供英文的schema.strings本地化,否则Spotlight会忽略整个架构。 (当然,也欢迎您提供其他本地化版本)。
检查您的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的空模式。
Spotlight并不总是能及时注意到变化。


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

mdimport -L

LaunchServices并不总是及时地注意到更改,而是将旧信息保留在周围。


如果您要在声明UTI的应用程序中对UTI的声明进行更改,或者对进口商为其注册的UTI进行更改,则LaunchServices和Spotlight可能会感到困惑。您可以使用以下方法完全重置LaunchServices并从标准位置重新读取它:

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

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



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

关于macos - 自定义Spotlight导入器和查找器的“更多信息”部分,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16354044/

相关文章:

objective-c - 有没有办法抑制 Xcode 中的警告?

objective-c - 如何在 macOS 系统偏好设置中启用 FinderSync 扩展

java - 使用 Maven 插件 Web.xml 未包含在 War 中

javascript - PhoneGap 3.0.0 : Unable To Instantiate Camera Plugin Object

c# - 如何为 C# 应用程序开发 C++ 插件?

python 在mac中批量重命名文件

macos - OS X 10.9 上的 QSettings - 无法找到/清除它

xcode - Sierra 上 xcode-select 的仅终端安装错误

swift - 获取 NSTableView 的第一个可见行

php - MYSQL PID/SOCK 错误 - 我无法让我的 Mac El Capitan 与完整的 Web 服务器配合使用