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.
- info->executable
- the output
/usr/bin/mdimport -n -d2 -g /path/to/your/importer.mdimporter /path/to/some/test/file.extcorrectly contains standard and/or custom metadata attributes intended. - you've deployed importer testing (either standalone in /library/spotlight/ or embedded in app bundle) ,
mdimport -llists importer. - but output of
mdls /some/other/file.extand/or finder's "get info" window doesn't show metadata attributes expected.
here's things check:
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
utexportedtypedeclarationskey in app's info.plist. - if you're importing third-party document type check app "owns" document type has declared uti in
utexportedtypedeclarationskey in app's info.plist. if app hasn't declared uti (some don't , still use oldcfbundledocumenttypes->cfbundletypeextensionskey instead) or if want importer work if app isn't installed have create "dummy" app sole purpose declare uti(s) inutimportedtypedeclarationskey 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
utimportedtypedeclarationsorutexportedtypedeclarationskeys 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 incfbundledocumenttypes->lsitemcontenttypeskey(s) in importer's info.plist.symptoms of someone else not having correctly declared uti
mdimport -n -d1 /some/file.extsays:imported '/some/file.ext' of type 'dyn.xxx' ...or (confusingly):imported '/some/file.ext' of type 'the.correct.uti' no plugin.
.
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
utimportedtypedeclarationsorutexportedtypedeclarationskey. in each uti declaration, app specifies 1 or more 'parent' utis in
uttypeconformstokey. 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.
- you can see current state of uti hierarchy poring on contents of launchservices database:
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 .
- you can see current state of metadata schema
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
allattrskey. 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
allattrskey document's uti, or parent utis, throws away value provided importer.
- spotlight looks document's uti in metadata schema. if there exists entry uti spotlight checks whether attribute importer returns listed under
.
- an app declares 1 or more utis in
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
displayattrskeys instead ofallattrskeys in metadata database. - the order in attributes displayed depends on position in metadata schema hierarchy.
.
- finder follows similar process spotlight above, except consults
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
mdcheckschemacommand 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,displayattrskeys - 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
displayattrskey. (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
attributessection , reference inallattrskey, 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.stringsproduct. - 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.stringssays:little-endian utf-16 unicode c program text.
a symptom of getting of above wrong
mdimport -x 2>&1 | grep -a20 uti.of.interesteither returns nothing or returns empty schema uti importer's schema.xml trying define.- the format custom schema.xml documented. unfortunately
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 -lcheck spotlight has noticed it's gone (this might take ~30s) before deploying updated version. typemdimport -lagain 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
- when testing updated version of importer first delete old importer (or entire app contains if it's embedded in app bundle) , type
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 userthis 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
Post a Comment