Custom Spotlight and Finder Importer Get More Info Information

I wrote Spotlight Importer for the type of custom document that defines my application.

Everything works fine, metadata fields are correctly indexed by Spotlight (verified using the mdls ), and Spotlight search shows my documents.

The only problem that I encountered is that the elements specified in the <displayattrs> section of the <displayattrs> file schema.xml not appear in the "Additional Information" section when I request information about the file (Cmd + I'm in the Finder).

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

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

The importer enters the application downloaded by the system ( mdimport -L confirmed this). In addition, the package structure seems to be correct, schema.xml displayed in the Resources folder, as well as schema.strings in the en / lproj folder.

Here's what the schema.xml file looks 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 few things, the mdcheckschema command is missing on my system, but the XML file is so short that I doubt the problem is with the syntax.
Sometimes in the "Additional Information" section the date of the last file opening is displayed, sometimes nothing.
Finally, I tried to rename the file ( mdimport ), but to no avail.

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

So, here is my question, have I missed something to display these elements in the "Additional Information" section? Is there anyone who experienced such a problem and found a solution?

Edit :

No one has yet answered my question, maybe someone can point me to some textbook or documentation about this problem?

+4
source share
1 answer

I know that Vince probably long ago resolved this (or refused). But I just spent quite some time working with various documented or completely undocumented problems with writing an importer, so it seemed to me that I would document my findings here. (I'm afraid it turned into an essay - this is a difficult question).

Suppose:

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

    To debug your importer in Xcode, select "Product-> Scheme-> Edit Scheme" and install:

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

    And set a breakpoint in your GetMetadataForURL () function.

  • The result 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 have deployed your importer for testing (stand-alone in / Library / Spotlight / or integrated in the application package), and mdimport -L is your importer.
  • But the output of the mdls /some/other/file.ext and / or Finder "Get Info" window does not display the expected metadata attributes.

Here are some things to check:

  • Someone else needs to declare a UTI for imported document types.

    • If you import a document of type system-declared , OSX has declared UTI for you.
    • If your importer is embedded in the application package, the application must declare UTI using the UTExportedTypeDeclarations key in the Info.plist application.
    • If you are importing a third-party document type, make sure that the application that owns the document type has declared a UTI for it in the UTExportedTypeDeclarations key in the Info.plist application. If the application does not declare UTI (some do not use and still use the old CFBundleDocumentTypesCFBundleTypeExtensions ) instead, or if you want your importer to work even if the application is not installed, you will have to create a “dummy” application, the only purpose which is the declaration of the UTI (s) in the UTImportedTypeDeclarations key in the Info.plist application. Install the "dummy" application somewhere like / Library / Application Support / myOrg / myApp.app. Your importer must be standalone and should not be integrated into this application package, since Spotlight will not launch importers from an application that the user has not opened.

    It makes no sense to declare the UTI (s) that you import into UTImportedTypeDeclarations or UTExportedTypeDeclarations in your Info.plist importer - LaunchServices will not read them reliably from there, so the Spotlight will not recognize them. However, you must register your interest in the UTI (s) by referencing them in the CFBundleDocumentTypesLSItemContentTypes keys in your Info.plist importer.

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

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

    .

  • If the attribute that your importer returns is not specified in the metadata schema for your UTI document or for any parent UTIs, then Spotlight throws that attribute away . Even if it is a standard attribute, for example kMDItemAuthors. To understand why, we need to see how Spotlight works in detail:

    • An application declares one or more UTIs in a UTImportedTypeDeclarations or UTExportedTypeDeclarations .
    • In each UTI declaration, the application indicates one or more "parent" UTIs in the UTTypeConformsTo key. Parent UTI should be something specific, if possible - for example. "public.image" if the application declares a new type of image file - or simply "public.data" if nothing suits.

      • You can see the current state of the UTI hierarchy by looking at the contents of the LaunchServices database: /System/Library/Frameworks/CoreServices.framework/Frameworks/LaunchServices.framework/Support/lsregister -dump .
      • But this is hard to understand. Fortunately, you are usually interested in the UTI hierarchy of a "clean" machine, which can be obtained using plutil -p /System/Library/CoreServices/CoreTypes.bundle/Contents/Info.plist .
    • Spotlight supports a “schema” that lists metadata attributes of interest to it:

      • You can see the current state of the metadata schema using mdimport -X 2>&1 .
      • You can see the clean machine metadata schema in /System/Library/Frameworks/CoreServices.framework/Frameworks/Metadata.framework/Resources/schema.plist.
    • When Spotlight decides what to store, it cross-references the output from your importer to both the UTI hierarchy and the metadata schema. Therefore, for each attribute returned by your importer:

      • Spotlight scans a UTI document in a metadata schema. If there is an entry for UTI, then Spotlight checks to see if the attribute that your importer returns is specified under the allattrs key. If so then Spotlight records the value provided by your importer in its database.
      • Otherwise, Spotlight searches for the parent UTI in the UTI hierarchy and repeats this process until it enters public.data.
      • If Spotlight cannot find the attribute specified in the allattrs key for your UTI document or for any parent UTIs, then it discards the value provided by your importer.

    .

  • If the attribute that is stored in the Spotlight database is not specified for display in the metadata schema for your UTI document or for any parent UTIs, then the Finder "Get Info" window will not be displayed . Even if it is a standard attribute, for example kMDItemAuthors.

    • The finder follows the same Spotlight process above, except that it accesses 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 hierarchy of the metadata schema.

    .

  • If you want to control which Spotlight stores and / or which Finder "Get Info" window is displayed, your importer must provide his own scheme.

    • The format for custom schema.xml is well documented. Unfortunately, the mdcheckschema command mentioned in the documentation no longer comes with Xcode. If you have a machine with an old version of OSX and 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 "Xcode 4.2 for Snow Leopard." Dmg.
    • You do not need to list all the attributes supported by your importer in the keys allattrs and displayattrs - only those attributes that are not specified for the parent or grandparents of 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 must specify the attributes that you want to display first in the desired order in displayattrs . (See, for example, "public.movie" in the scheme, which duplicates some of the keys from the parent "public.audiovisual-content", so that they are displayed first).
    • Your schema must define at least one custom attribute in the attributes section and reference it in the allattrs key, otherwise Spotlight ignores the whole schema. If your importer does not provide any custom attributes, then just add the dummy custom attribute to the schema. (This claim came some time after Snow Leopard and is completely undocumented, and probably where Vince was wrong).
    • If your schema defines a user attribute (and it should, see the previous point), then you must supply the English localization of schema.strings, otherwise Spotlight ignores the whole schema. (Of course, you can also provide other localizations).
    • Make sure you have the “Stock Copy” phase in your Xcode project that copies schema.xml and schema.strings into your product.
    • Double check that the contents / Resources / schema.xml and the Contents / Resources / ru.lproj / schema.strings or the Contents / Resources / English.lproj / schema.strings really exist in your embedded product; some older versions of Xcode did not copy them.
    • Make sure file /path/to/your/built/importer.mdimporter/Contents/Resources/en.lproj/schema.strings says:
      • Little-endian UTF-16 Unicode c program text .

    The symptom of getting any of the above errors is that mdimport -X 2>&1 | grep -A20 uti.of.interest mdimport -X 2>&1 | grep -A20 uti.of.interest either returns nothing or returns an empty UTI schema that your importporter schema.xml is trying to define.

  • Spotlight does not always notice changes in a timely manner.

    • When testing an updated version of your importer, first remove the old importer (or the entire application that contains it, if it is included in the application package) and enter mdimport -L to verify that Spotlight noticed that it was gone (this may take ~ 30 seconds) before deploying your updated version. Type mdimport -L again to verify that Spotlight has noticed the updated version (again it may take about 30 seconds) before resuming testing.
    • If you distribute the standalone importer in the .pkg file, you must enable the postinstall script in 1: tell LaunchServices that the package has been updated (Installer does this automatically for applications, but not for other types of packages) and 2: hit Spotlight to re-index for the current user types of documents that your importer understands:

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

  • LaunchServices does not always notice changes in a timely manner and stores old information.

    • If you make changes to the declaration of the UTI (s) in the application declaring them or in the UTI (s) that your importer registers, then LaunchServices and Spotlight may be confused. You can completely reset LaunchServices and get it for re-reading from standard places:

      /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” installation of your importer and / or application in your development system.

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

+10
source

Source: https://habr.com/ru/post/1478931/


All Articles