自定义Spotlight导入器和Finder的获取信息“更多信息”部分 [英] Custom Spotlight Importer and Finder's Get Info "More Info" section

查看:284
本文介绍了自定义Spotlight导入器和Finder的获取信息“更多信息”部分的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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



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



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



我希望这些字段出现在那里,因为我在< allattrs> < displayattrs> 部分。





进口商捆绑到应用程序中,由系统加载( mdimport -L 确认此)。
另外,bundle的结构是正确的, 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:///系统/ 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 ),无效。 / p>

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



问题,我缺少某些东西,让这些项目显示在更多信息部分?
是否有人遇到过这样的问题,并找到了解决方案?



修改



没有人回答我的问题,也许有人可以告诉我一些关于这个问题的教程或文档。

解决方案

我知道文斯可能早就解决了这个问题(或放弃了)。但我刚刚花了一个令人沮丧的长时间工作通过各种记录不足或完全无证的问题,写一个进口商,所以我想我会在这里记录我的发现。 (我恐怕这已经变成了一篇文章 - 这是一个复杂的主题)。



让我们假设:





以下是一些需要检查的事项:


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




    • 如果要导入文档系统声明的

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



    没有点声明您在 UTImportedTypeDeclarations 中导入的UTI s UTExportedTypeDeclarations 键在导入器的Info.plist中 - LaunchServices将无法可靠地从中读取,因此Spotlight无法识别它们。但是,您必须在 CFBundleDocumentTypes - > LSItemContentTypes 引用,注册您对UTI的兴趣



    其他人没有正确宣布UTI的症状是

    code> mdimport -n -d1 /some/file.ext
    说:




    • 导入类型为'dyn.xxx'... 或(混淆地)的'/some/file.ext':

    • 导入'ofthecorrect.uti'类型的'/some/file.ext',没有plugIn




  2. 如果您的导入器返回的属性未在您的文档的UTI或任何父UTI的元数据架构中列出, > Spotlight throw that that attribute away 。即使它是一个标准属性,如kMDItemAuthors。要了解原因,我们需要详细了解Spotlight的工作原理:




    • 应用程序在<$ c $中声明一个或多个UTI c> UTImportedTypeDeclarations UTExportedTypeDeclarations 键。

    • 在每个UTI声明中,或更多的父UTI在 UTTypeConformsTo 键。如果可能,父UTI应该是特定的。 public.image如果应用程序声明一个新类型的图像文件 - 或只是public.data,如果没有其他适当的。




      • 您可以通过遍历LaunchServices数据库的内容来查看UTI层次结构的当前状态: /System/Library/Frameworks/CoreServices.framework/Frameworks/LaunchServices.framework/Support/lsregister -dump

      • 但是这很难解密。幸运的是,你通常会对清洁机器的UTI层次感兴趣,可以通过 plutil -p /System/Library/CoreServices/CoreTypes.bundle/Contents/Info.plist


    • Spotlight维护一个模式,列出其感兴趣的元数据属性: p>


      • 您可以使用 mdimport -X 2>& 1

      • 您可以在/System/Library/Frameworks/CoreServices.framework/Frameworks/Metadata.framework/Resources/schema.plist中查看干净机器的元数据模式。


    • 当Spotlight决定要存储什么时,它将交叉引用导入器的输出同时针对UTI层次结构和元数据模式。因此,对于您的导入器返回的每个属性:




      • Spotlight在元数据模式中查找文档的UTI。如果存在UTI的条目,Spotlight会检查您的导入器返回的属性是否列在 allattrs 键下。

      • 否则Spotlight会在UTI层次结构中查找父UTI,并重复此过程,直到达到public.data 。

      • 如果Spotlight找不到您的文档的UTI或任何父UTI的 allattrs 键中列出的属性,它会丢弃您的进口商提供的价值。





  3. 如果存储在Spotlight数据库中的属性未列出显示在文档的UTI或任何父UTI的元数据架构中,则 Finder的获取信息窗口将不会显示




    • Finder遵循与Spotlight类似的流程,只是它查询了 displayattrs 键而不是元数据数据库中的 allattrs 键。

    • 属性的顺序


    • 如果您想要控制Spotlight存储的内容和/或Finder的获取信息窗口,那么您的导入器需要提供自定义模式。




      • 自定义schema.xml的格式已有相当详细的文档。不幸的是,文档中提到的 mdcheckschema 命令不再包含Xcode。如果你有一台机器的旧版本的OSX& Xcode可以从 / usr / bin / mdcheckschema 中复制它。如果您有Apple开发者帐户,可以在Xcode 4.2 for Snow Leoparddmg中从/Packages/DeveloperToolsCLI.pkg中提取。

      • 您不必列出每个属性您的导入程序支持 allattrs displayattrs 键 - 只有那些属性在/System/Library/Frameworks/CoreServices.framework/Frameworks/Metadata.framework/Resources/schema.plist中为父级或祖父级UTI列出。

      • 但是,如果要控制<其中属性显示在获取信息窗口中,应该在 displayattrs 键中列出您希望按照所需顺序显示的属性。 (例如,请参阅模式中的public.movi​​e,它从父代public.audiovisual-content复制一些键,以便首先显示它们。)

      • strong>必须在属性部分中定义至少一个自定义属性,并在 allattrs 键,否则Spotlight会忽略整个模式。如果您的导入器不提供任何自定义属性,那么只是添加一个假的自定义属性到架构。

      • 如果你的模式定义了一个自定义属性(它应该;见上一点),那么您必须为其提供英语schema.strings本地化,否则Spotlight会忽略整个模式。 (当然也欢迎提供其他本地化版本)。

      • 检查您的Xcode项目中是否有复制捆绑资源阶段,它复制模式。

      • 仔细检查内容/资源/模式。
      • xml和Contents / Resources / en.lproj / schema.strings或Contents / Resources / English.lproj / schema.strings 真的;
      • 请检查文件/path/to/your/built/importer.mdimporter/Contents/Resources/en .lproj / schema.strings 说:


        • Little-endian UTF-16 Unicode c程序文本




      错误的是 mdimport -X 2>& 1 | grep -A20 uti.of.interest 不返回任何内容或返回一个空模式,您的导入器的schema.xml尝试定义的UTI。


      <




      • 在测试更新版本的导入程序时,请先删除旧的导入器(如果嵌入应用程序包中,则包含它的整个应用程序),然后键入 mdimport -L 以检查Spotlight是否注意到它已经消失30秒),然后再部署更新的版本。再次键入 mdimport -L 以检查Spotlight是否已注意到更新的版本(这可能需要大约30秒),然后才能继续测试。

      • 如果您在.pkg文件中分发独立导入程序,则应该在postinstall脚本中包含1:tell LaunchServices该软件包已更新(安装程序会自动为应用程序执行此操作,但不会为其他捆绑类型执行此操作)和2:将Spotlight转入为当前用户重新索引您的导入程序可以理解的文档类型:



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



    • LaunchServices




      • 如果您要更改UTI的声明s)在应用程序中声明它们,或者您的进口商注册的UTI,然后LaunchServices和Spotlight可能会困惑。您可以完全重置LaunchServices,并使其从标准位置重新读取:



        /System/Library/Frameworks/CoreServices.framework/Frameworks /LaunchServices.framework/Support/lsregister -v -kill -seed -domain system -domain network -domain local -domain user



        这是



    • 如果您想在开发系统上模拟干净安装导入程序和/ ol>

      编辑: gitHub上的此项目说明点1- 5以上。


      I have written a Spotlight Importer for the custom document type my application defines.

      Everything is working fine, the metadata fields are correctly indexed by Spotlight (verified using mdls command), and a Spotlight search reveals my documents.

      The only problem I have is that items I specify in the <displayattrs> section of the schema.xml file aren't displayed in the "More Info" section when I ask for informations about a file (Cmd+I in the Finder).

      I expected these fields to appear there because I declared them both in the <allattrs> and <displayattrs> sections.

      I found few questions here related to this problem, none of them helped me.

      The importer is bundled into the app, loaded by the system (mdimport -L confirmed this). Also, the bundle structure seems right, the schema.xml appears in the Resources folder, as well as the schema.strings in the en/lproj folder.

      Here is what the schema.xml file look like :

      <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>
      

      A couple of things more, my system is lacking the mdcheckschema command, but the XML file is so short, I doubt there is a problem with the syntax.
      Sometimes, the "More Info" section display the file last opening date, sometimes nothing.
      Finally, I tried reimporting the file (mdimport), to no avail.

      I'm running Mac OS X Moutain Lion 10.8.3, Xcode 4.6.2.

      So here my question, am I missing something to have those items displayed in the "More Info" section ? Is there someone who has experienced such a problem and found a solution ?

      Edit :

      Nobody answered my question so far, maybe someone can point me to some tutorial or documentation about this problem ?

      解决方案

      I know that Vince has probably long since solved this (or given up). But I've just spent a frustratingly long time working through various poorly documented or totally undocumented issues with writing an importer, so I thought I'd document my findings here. (I'm afraid this has turned into an essay - it's a complicated subject).

      Let's assume:

      • You've read the documentation on how to write a Spotlight importer, in particular the troubleshooting guide.
      • You've written and debugged your importer.

        To debug your importer in Xcode choose Product->Scheme->Edit Scheme and set:

        • Info->Executable to /usr/bin/mdimport
        • Arguments->Arguments to -n -d2 -g $(BUILT_PRODUCTS_DIR)/$(WRAPPER_NAME) /path/to/some/test/file.ext
        • Options->Working Directory to $(SRCROOT)

        And set a breakpoint on your GetMetadataForURL() function.

      • The output from /usr/bin/mdimport -n -d2 -g /path/to/your/importer.mdimporter /path/to/some/test/file.ext correctly contains the standard and/or custom metadata attributes that you intended.
      • You've deployed your importer for testing (either standalone in /Library/Spotlight/ or embedded in an app bundle) and mdimport -L lists your importer.
      • But the output of mdls /some/other/file.ext and/or Finder's "Get Info" window doesn't show the metadata attributes that you expected.

      Here's some things to check:

      1. Someone else needs to declare the UTI(s) for the document type(s) that you're importing.

        • If you're importing a document of a system-declared type then OSX has declared the UTI for you.
        • If your importer is embedded in an app bundle, then the app should declare the UTI via a UTExportedTypeDeclarations key in the app's Info.plist.
        • If you're importing a third-party document type then check that the app that "owns" the document type has declared a UTI for it in a UTExportedTypeDeclarations key in the app's Info.plist. If the app hasn't declared a UTI (some don't and still use the old CFBundleDocumentTypes->CFBundleTypeExtensions key instead) or if you want your importer to work even if the app isn't installed then you will have to create a "dummy" app whose sole purpose is to declare the UTI(s) in a UTImportedTypeDeclarations key in the app's Info.plist. Install the "dummy" app somewhere like /Library/Application Support/myOrg/myApp.app. Your importer should be standalone and should not be embedded in this app's bundle since Spotlight won't run importers from an app that the user hasn't opened.

        There's no point declaring the UTI(s) that you're importing in UTImportedTypeDeclarations or UTExportedTypeDeclarations keys in your importer's Info.plist - LaunchServices won't reliably read them from there so Spotlight won't recognise them. However you must register your interest in the UTI(s) by refering to them in CFBundleDocumentTypes->LSItemContentTypes key(s) in your importer's Info.plist.

        Symptoms of someone else not having correctly declared a UTI are that mdimport -n -d1 /some/file.ext says:

        • Imported '/some/file.ext' of type 'dyn.xxx' ... or (confusingly):
        • Imported '/some/file.ext' of type 'the.correct.uti' with no plugIn.

        .

      2. If an attribute that your importer returns is not listed in the metadata schema for your document's UTI, or for any parent UTIs, then Spotlight throws that attribute away. Even if it's a standard attribute like kMDItemAuthors. To understand why, we need to look at how Spotlight works in detail:

        • An app declares one or more UTIs in a UTImportedTypeDeclarations or UTExportedTypeDeclarations key.
        • In each UTI declaration, the app specifies one or more 'parent' UTIs in a UTTypeConformsTo key. The parent UTI should be something specific if possible - e.g. "public.image" if the app is declaring a new type of image file - or just "public.data" if nothing else is appropriate.

          • You can see the current state of the UTI hierarchy by poring over the contents of the LaunchServices database: /System/Library/Frameworks/CoreServices.framework/Frameworks/LaunchServices.framework/Support/lsregister -dump .
          • But that's tricky to decipher. Fortunately you'll normally be more interested in the UTI hierarchy of a 'clean' machine which can be obtained by plutil -p /System/Library/CoreServices/CoreTypes.bundle/Contents/Info.plist .
        • Spotlight maintains a "schema" which lists the metatdata attributes of interest to it:

          • You can see the current state of the metadata schema with mdimport -X 2>&1 .
          • You can see the the metadata schema of a 'clean' machine in /System/Library/Frameworks/CoreServices.framework/Frameworks/Metadata.framework/Resources/schema.plist .
        • When Spotlight is deciding what to store it cross-references the output of your importer against both the UTI hierarchy and the metadata schema. So for each attribute that your importer returns:

          • Spotlight looks up the document's UTI in the metadata schema. If there exists an entry for the UTI then Spotlight checks whether the attribute that your importer returns is listed under the allattrs key. If it is then Spotlight records the value provided by your importer in its database.
          • Otherwise Spotlight looks up the parent UTI in the UTI hierarchy and repeats the process until it hits "public.data".
          • If Spotlight can't find the attribute listed in the allattrs key for your document's UTI, or for any parent UTIs, then it throws away the value provided by your importer.

        .

      3. If an attribute that is stored in the Spotlight database is not listed for display in the metadata schema for your document's UTI, or for any parent UTIs, then Finder's "Get Info" window won't display it. Even if it's a standard attribute like kMDItemAuthors.

        • Finder follows a similar process to Spotlight above, except that it consults the displayattrs keys instead of the allattrs keys in the metadata database.
        • The order in which attributes are displayed depends on their position in the metadata schema hierarchy.

        .

      4. If you want to control what Spotlight stores and/or what Finder's "Get Info" window displays then your importer needs to supply a custom schema.

        • The format for the custom schema.xml is fairly well documented. Unfortunately the mdcheckschema command mentioned in the documentation no longer ships with Xcode. If you have a machine with an older version of OSX & Xcode you can copy it from /usr/bin/mdcheckschema. If you have an Apple Developer account you can extract it from /Packages/DeveloperToolsCLI.pkg on the "Xcode 4.2 for Snow Leopard" dmg.
        • You don't have to list every attribute that your importer supports in the allattrs and displayattrs keys - only those attributes that aren't listed for a parent or grandparent UTI in /System/Library/Frameworks/CoreServices.framework/Frameworks/Metadata.framework/Resources/schema.plist .
        • However if you want to control the order in which attributes are displayed in the "Get Info" window you should list the attributes that you want displayed first in your desired order in the displayattrs key. (See for example "public.movie" in the schema, which duplicates some keys from its parent "public.audiovisual-content" so that they're displayed first).
        • Your schema must define at least one custom attribute in the attributes section and reference to it in an allattrs key, otherwise Spotlight ignores the whole schema. If your importer doesn't supply any custom attributes then just add a bogus custom attribute to the schema anyway. (This requirement arrived some time after Snow Leopard and is completely undocumented, and is probably where Vince was going wrong).
        • If your schema defines a custom attribute (and it should; see previous point) then you must supply an English schema.strings localization for it, otherwise Spotlight ignores the whole schema. (Of course you're welcome to provide other localizations too).
        • Check that you have a "Copy Bundle Resources" phase in your Xcode project that copies schema.xml and schema.strings into your product.
        • Double-check that Contents/Resources/schema.xml and Contents/Resources/en.lproj/schema.strings or Contents/Resources/English.lproj/schema.strings really exist in your built product; some older versions of Xcode didn't copy them across.
        • Check that file /path/to/your/built/importer.mdimporter/Contents/Resources/en.lproj/schema.strings says:
          • Little-endian UTF-16 Unicode c program text .

        A symptom of getting any of the above wrong is that mdimport -X 2>&1 | grep -A20 uti.of.interest either returns nothing or returns an empty schema for the UTI that your importer's schema.xml is trying to define.

      5. Spotlight doesn't always notice changes in a timely manner.

        • When testing an updated version of your importer first delete the old importer (or the entire app that contains it if it's embedded in an app bundle) and type mdimport -L to check that Spotlight has noticed that it's gone (this might take ~30s) before deploying your updated version. Type mdimport -L again to check that Spotlight has noticed the updated version (again this might take ~30s) before resuming testing.
        • If you're distributing a standalone importer in a .pkg file, then you should include a postinstall script to 1: tell LaunchServices that the bundle has been updated (Installer does this automatically for apps, but not for other bundle types) and 2: kick Spotlight into re-indexing for the current user the document types that your importer understands:

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

      6. LaunchServices doesn't always notice changes in a timely manner, and keeps old information lying around.

        • If you're making changes to the declaration of the UTI(s) in the app that declares them, or to the UTI(s) that your importer registers for then LaunchServices and Spotlight can get confused. You can completely reset LaunchServices and get it to re-read from standard places with:

          /System/Library/Frameworks/CoreServices.framework/Frameworks/LaunchServices.framework/Support/lsregister -v -kill -seed -domain system -domain network -domain local -domain user

          This is also useful if you want to simulate a 'clean' install of your importer and/or app on your development system.

      Edit: This project on gitHub illustrates points 1-5 above.

      这篇关于自定义Spotlight导入器和Finder的获取信息“更多信息”部分的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆