osx - Custom Spotlight Importer and Finder's Get Info "More Info" section -


i have written spotlight importer custom document type application defines.

everything working fine, metadata fields correctly indexed spotlight (verified using mdls command), , spotlight search reveals documents.

the problem have items specify in <displayattrs> section of schema.xml file aren't displayed in "more info" section when ask informations file (cmd+i in finder).

i expected these fields appear there because declared them both in <allattrs> , <displayattrs> sections.

i found few questions here related problem, none of them helped me.

the importer bundled app, loaded system (mdimport -l confirmed this). also, bundle structure seems right, schema.xml appears in resources folder, schema.strings in en/lproj folder.

here schema.xml file :

<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, system lacking mdcheckschema command, xml file short, doubt there problem syntax.
sometimes, "more info" section display file last opening date, nothing.
finally, tried reimporting file (mdimport), no avail.

i'm running mac os x moutain lion 10.8.3, xcode 4.6.2.

so here question, missing have items displayed in "more info" section ? there has experienced such problem , found solution ?

edit :

nobody answered question far, maybe can point me tutorial or documentation problem ?

i know vince has long since solved (or given up). i've spent frustratingly long time working through various poorly documented or totally undocumented issues writing importer, thought i'd document findings here. (i'm afraid has turned essay - it's complicated subject).

let's assume:

  • you've read documentation on how write spotlight importer, in particular troubleshooting guide.
  • you've written , debugged importer.

    to debug importer in xcode choose product->scheme->edit scheme , set:

    • info->executable /usr/bin/mdimport
    • arguments->arguments -n -d2 -g $(built_products_dir)/$(wrapper_name) /path/to/some/test/file.ext
    • options->working directory $(srcroot)

    and set breakpoint on getmetadataforurl() function.

  • the output /usr/bin/mdimport -n -d2 -g /path/to/your/importer.mdimporter /path/to/some/test/file.ext correctly contains standard and/or custom metadata attributes intended.
  • you've deployed importer testing (either standalone in /library/spotlight/ or embedded in app bundle) , mdimport -l lists importer.
  • but output of mdls /some/other/file.ext and/or finder's "get info" window doesn't show metadata attributes expected.

here's things check:

  1. someone else needs declare uti(s) document type(s) you're importing.

    • if you're importing document of system-declared type osx has declared uti you.
    • if importer embedded in app bundle, app should declare uti via utexportedtypedeclarations key in app's info.plist.
    • if you're importing third-party document type check app "owns" document type has declared uti in utexportedtypedeclarations key in app's info.plist. if app hasn't declared uti (some don't , still use old cfbundledocumenttypes->cfbundletypeextensions key instead) or if want importer work if app isn't installed have create "dummy" app sole purpose declare uti(s) in utimportedtypedeclarations key in app's info.plist. install "dummy" app somewhere /library/application support/myorg/myapp.app. importer should standalone , should not embedded in app's bundle since spotlight won't run importers app user hasn't opened.

    there's no point declaring uti(s) you're importing in utimportedtypedeclarations or utexportedtypedeclarations keys in importer's info.plist - launchservices won't reliably read them there spotlight won't recognise them. must register interest in uti(s) refering them in cfbundledocumenttypes->lsitemcontenttypes key(s) in importer's info.plist.

    symptoms of someone else not having correctly declared uti 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' no plugin.

    .

  2. if attribute importer returns not listed in metadata schema document's uti, or parent utis, spotlight throws attribute away. if it's standard attribute kmditemauthors. understand why, need @ how spotlight works in detail:

    • an app declares 1 or more utis in utimportedtypedeclarations or utexportedtypedeclarations key.
    • in each uti declaration, app specifies 1 or more 'parent' utis in uttypeconformsto key. parent uti should specific if possible - e.g. "public.image" if app declaring new type of image file - or "public.data" if nothing else appropriate.

      • you can see current state of uti hierarchy poring on contents of launchservices database: /system/library/frameworks/coreservices.framework/frameworks/launchservices.framework/support/lsregister -dump .
      • but that's tricky decipher. fortunately you'll more interested in uti hierarchy of 'clean' machine can obtained plutil -p /system/library/coreservices/coretypes.bundle/contents/info.plist .
    • spotlight maintains "schema" lists metatdata attributes of interest it:

      • you can see current state of metadata schema mdimport -x 2>&1 .
      • you can see the metadata schema of 'clean' machine in /system/library/frameworks/coreservices.framework/frameworks/metadata.framework/resources/schema.plist .
    • when spotlight deciding store cross-references output of importer against both uti hierarchy , metadata schema. each attribute importer returns:

      • spotlight looks document's uti in metadata schema. if there exists entry uti spotlight checks whether attribute importer returns listed under allattrs key. if spotlight records value provided importer in database.
      • otherwise spotlight looks parent uti in uti hierarchy , repeats process until hits "public.data".
      • if spotlight can't find attribute listed in allattrs key document's uti, or parent utis, throws away value provided importer.

    .

  3. if attribute stored in spotlight database not listed display in metadata schema document's uti, or parent utis, finder's "get info" window won't display it. if it's standard attribute kmditemauthors.

    • finder follows similar process spotlight above, except consults displayattrs keys instead of allattrs keys in metadata database.
    • the order in attributes displayed depends on position in metadata schema hierarchy.

    .

  4. if want control spotlight stores and/or finder's "get info" window displays importer needs supply custom schema.

    • the format custom schema.xml documented. unfortunately mdcheckschema command mentioned in documentation no longer ships xcode. if have machine older version of osx & xcode can copy /usr/bin/mdcheckschema. if have apple developer account can extract /packages/developertoolscli.pkg on "xcode 4.2 snow leopard" dmg.
    • you don't have list every attribute importer supports in allattrs , displayattrs keys - attributes aren't listed parent or grandparent uti in /system/library/frameworks/coreservices.framework/frameworks/metadata.framework/resources/schema.plist .
    • however if want control order in attributes displayed in "get info" window should list attributes want displayed first in desired order in displayattrs key. (see example "public.movie" in schema, duplicates keys parent "public.audiovisual-content" they're displayed first).
    • your schema must define @ least 1 custom attribute in attributes section , reference in allattrs key, otherwise spotlight ignores whole schema. if importer doesn't supply custom attributes add bogus custom attribute schema anyway. (this requirement arrived time after snow leopard , undocumented, , vince going wrong).
    • if schema defines custom attribute (and should; see previous point) must supply english schema.strings localization it, otherwise spotlight ignores whole schema. (of course you're welcome provide other localizations too).
    • check have "copy bundle resources" phase in xcode project copies schema.xml , schema.strings product.
    • double-check contents/resources/schema.xml , contents/resources/en.lproj/schema.strings or contents/resources/english.lproj/schema.strings really exist in built product; older versions of xcode didn't copy them across.
    • check 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 of above wrong mdimport -x 2>&1 | grep -a20 uti.of.interest either returns nothing or returns empty schema uti importer's schema.xml trying define.

  5. spotlight doesn't notice changes in timely manner.

    • when testing updated version of importer first delete old importer (or entire app contains if it's embedded in app bundle) , type mdimport -l check spotlight has noticed it's gone (this might take ~30s) before deploying updated version. type mdimport -l again check spotlight has noticed updated version (again might take ~30s) before resuming testing.
    • if you're distributing standalone importer in .pkg file, should include postinstall script 1: tell launchservices bundle has been updated (installer automatically apps, not other bundle types) , 2: kick spotlight re-indexing current user document types importer understands:

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

  6. launchservices doesn't notice changes in timely manner, , keeps old information lying around.

    • if you're making changes declaration of uti(s) in app declares them, or uti(s) importer registers launchservices , spotlight can confused. can reset launchservices , re-read 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 useful if want simulate 'clean' install of importer and/or app on development system.

edit: this project on github illustrates points 1-5 above.


Comments

Popular posts from this blog

php - Why I am getting the Error "Commands out of sync; you can't run this command now" -

linux - Does gcc have any options to add version info in ELF binary file? -

java - Are there any classes that implement javax.persistence.Parameter<T>? -