Troubleshooting Spotlight Importers
Rare is the project that is flawless from the start. Troubleshooting a Spotlight importer can be difficult given that it is run by the system automatically as required and is run outside the development environment.
This article describes how to explicitly run your metadata importer for testing and provides a number of techniques for troubleshooting problems.
Where should I install my Spotlight importer?
An application’s Spotlight importer resides within the application’s bundle in the subdirectory MyApp.app/Contents/Library/Spotlight
. Standalone importers can be installed in one of the following locations:
~/Library/Spotlight |
/Library/Spotlight |
If your importer is not part of an application bundle, create an installer package that installs the importer in one of the above locations. To have existing files imported, you need to have a postinstall
script for your installer that includes the following command, specifying your importer installation location:
/usr/bin/mdimport -r InstallDirectory/YourPlug-In |
When will the Spotlight importer in my application bundle re-index files?
When a user first runs your application, the Spotlight importer is found and Spotlight begins importing any existing files. If you update your application and the Spotlight importer, make sure that the importer bundle has a different date stamp. When the updated application is run for the first time Spotlight reindexes the existing files with the new importer.
How can I determine whether my Spotlight importer is being found?
Running the mdimport
command (located in /usr/bin
) with the -L
option returns a list of all the currently recognized importers and their paths.
/usr/bin/mdimport -L |
2005-01-16 02:56:37.634 mdimport[673] Paths: id(501) ( |
"/System/Library/Spotlight/RichText.mdimporter", |
"/System/Library/Spotlight/Image.mdimporter", |
"/System/Library/Spotlight/Audio.mdimporter", |
"/System/Library/Spotlight/Font.mdimporter", |
"/System/Library/Spotlight/PDF.mdimporter", |
"/System/Library/Spotlight/Chat.mdimporter", |
"/System/Library/Spotlight/iCal.mdimporter", |
"/System/Library/Spotlight/Mail.mdimporter", |
"/System/Library/Spotlight/QuickTime.mdimporter", |
"/System/Library/Spotlight/vCard.mdimporter", |
"/Users/me/Library/Spotlight/MyCustomImporter.mdimporter", |
"/System/Library/Spotlight/QuartzComposer.mdimporter", |
"/System/Library/Spotlight/PS.mdimporter", |
"/System/Library/Spotlight/SystemPrefs.mdimporter", |
"/System/Library/Spotlight/Application.mdimporter" |
) |
Why isn’t my bundled importer being found?
If your importer resides within your application’s wrapper, it may not be found automatically during testing. Importers are detected when the bundle’s modification date is changed. You can explicitly register your application by specifying the -f
flag to lsregister
. The lsregister
tool is found in /System/Library/Frameworks/CoreServices.framework/Frameworks/LaunchServices.framework/Versions/A/Support/
on OS X v10.5 and later.
lsregister -f MyApp.app |
Another possibility is that your application may be untrusted. Spotlight importers are not loaded from untrusted applications. Launching the application for the first time causes the application to be trusted.
I've updated my importer and copied it to a Spotlight directory, but the old importer is still being used
New Spotlight importers are detected by comparing the importer’s modification date. If the date is the same as a previously loaded importer, the new importer is not automatically detected. If you copy the updated importer to the Spotlight directory using cp -r
, the change is not noted by Spotlight. The solution is to either remove the existing importer before copying the updated version, or use the touch
command on the importer .mdimporter
directory to explicitly update the date.
How do I test my importer?
You can test your Spotlight importer using the mdimport
command (located in /usr/bin
). Run mdimport
with the debug level set to 2 and specify a file that you can import data from:
/usr/bin/mdimport -d2 test.myCustomDocument |
This command produces out like this:
2005-01-16 02:59:04.930 mdimport[678] Import '/Users/me/Documents/test.myCustomDocument' |
type 'com.apple.mycocoadocumentapp.mycustomdocument' |
using 'file://localhost/Users/me/Library/Spotlight/MyCustomImporter.mdimporter/' |
2005-01-16 02:59:04.931 mdimport[678] Sending attributes |
of '/Users/me/Documents/test.myCustomDocument' to server. |
Attributes: '{ |
"_kMDItemImporterCrashed" = <null>; |
"com_apple_metadata_modtime" = 127555123.1940155; |
"com_apple_myCocoaDocumentApp_myCustomDocument_notes" = "Remember to feed the cats!"; |
kMDItemAuthors = ("Tori”,”Simon",”Daniel”); |
kMDItemContentType = "com.apple.mycocoadocumentapp.mycustomdocument"; |
kMDItemContentTypeTree = ("com.apple.mycocoadocumentapp.mycustomdocument", "public.data", "public.item"); |
kMDItemDisplayName = {"" = "test.myCustomDocument"; }; |
kMDItemKind = {en = DocumentType; }; |
kMDItemTitle = "Be sure to remember to..."; |
}' |
The first line of the output indicates the file that is being imported, as well as the UTI that the file maps to. The remaining lines list the attribute keys and values that were imported from the file.
You should ensure that all the appropriate metadata keys that your importer returns are present in the output. You'll notice that a number of metadata keys specific to the file system are also available for each file. These are provided by the metadata system and are not your responsibility.
How do I debug my importer using gdb?
You can debug your importer by running mdimport
under gdb
.
The following command loads mdimport
under gdb
:
gdb mdimport |
After mdimport
has started, set a breakpoint on your import function:
b MyImporterGetAttributesFromFileFunction |
Then start the mdimport
process, specifying the file to import:
r /path/to/my/test/file |
What does the system think the UTI is for a file?
You can determine the UTI that the system thinks belongs to your file by using the mdimport
command with a debug level of 1:
/usr/bin/mdimport -d1 test.myCustomDocument |
The output shows the UTI type that the system has determined for the file:
2005-01-16 03:00:07.212 mdimport[683] Import '/Users/me/Documents/ test.myCustomDocument' |
type 'com.apple.mycocoadocumentapp.mycustomdocument' using |
'file://localhost/Users/me/Library/Spotlight/MyCustomImporter.mdimporter/' |
The type should match the UTI that your importer supports.
Running mdimport returns nothing
If running mdimport
with a debug level of 1 returns no output, you should ensure that the file you're attempting to import is not in the /tmp
directory or some other System directory. Files in those locations are not imported.
Running mdimport returns an unexpected UTI
If running mdimport
returns a UTI other than one you expect, you'll need to ensure that the file you're attempting to import is actually the type of file you think it is. The UTI of a file is determined by the extension or file type.
It is also possible that a dynamic UTI is returned:
2005-01-16 03:01:16.989 mdimport[691] Import '/Users/me/Documents/test.myCustomDocument' |
type 'dyn.ah62d4rv4ge8048pdsz31k55rqv10g7prqz1hkqu' no mdimporter |
Typically, the return of a dynamic UTI indicates that the file is not mapping to a known UTI. You should check that:
The test file is the correct file type.
The test file has the correct filename extension or file type set.
If your application is declaring the UTI type for the file, that the application’s
Info.plist
file has the correct entries in theUTExportedTypeDeclarations
entry as shown here:<key>UTExportedTypeDeclarations</key>
<array>
<dict>
<key>UTTypeConformsTo</key>
<array>
<string>public.data</string>
</array>
<key>UTTypeDescription</key>
<string>My Document Type</string>
<key>UTTypeIdentifier</key>
<string>com.apple.mycocoadocumentapp.mycustomdocument</string>
<key>UTTypeTagSpecification</key>
<dict>
<key>public.filename-extension</key>
<array>
<string>myCustomDocument</string>
</array>
<key>com.apple.ostype</key>
<string>T78q</string>
</dict>
</dict>
</array>
Ensure that your application lives in a location where Launch Services can detect the mappings. Running the application also ensures that the mappings are made.
mdimport does not return my metadata attributes
If running mdimport
with a debug level of 3 does not list any of your custom metadata attributes, you should check that:
Your metadata importer is being found using the
mdimport -L
command.Your metadata importer's
Info.plist
file has the correct plug-in type for metadata importers in theCFPlugInTypes
entry. The key should be8B08C4BF-415B-11D8-B3F9-0003936726FC
:<key>CFPlugInTypes</key>
<dict>
<key>8B08C4BF-415B-11D8-B3F9-0003936726FC</key>
<array>
<string>8AED83B3-C412-11D8-85A3-000393D59866</string>
</array>
</dict>
The UUID that you created for your importer is unique and is in both the
CFPlugInFactories
andCFPluginTypes
entries of the importer'sInfo.plist
file. Here, the UUID is8AED83B3-C412-11D8-85A3-000393D59866
:<key>CFPlugInFactories</key>
<dict>
<key>8AED83B3-C412-11D8-85A3-000393D59866</key>
<string>MetadataImporterPluginFactory</string>
</dict>
<key>CFPlugInTypes</key>
<dict>
<key>8B08C4BF-415B-11D8-B3F9-0003936726FC</key>
<array>
<string>8AED83B3-C412-11D8-85A3-000393D59866</string>
</array>
</dict>
You have the correct UTI type for your importer listed in the
LSItemContentTypes
entry in the importer’sInfo.plist
file:<key>CFBundleDocumentTypes</key>
<array>
<dict>
<key>CFBundleTypeRole</key>
<string>MDImporter</string>
<key>LSItemContentTypes</key>
<array>
<string>com.apple.mycocoadocumentapp.mycustomdocument</string>
</array>
</dict>
</array>
Your UTI is all lowercase in the
Info.plist
and theschema.xml
files.If your importer reads metadata from a file bundle, ensure that the
UTTypeConformsTo
entry in the importer'sInfo.plist
file includescom.apple.package
as the file UTI.Your
schema.xml
file is valid.You can test whether your
schema.xml
file is well formed by running the commandmdcheckschema
(located in/usr/bin
)./usr/bin/mdcheckschema ~/Library/Spotlight/MyCustomImporter.mdimporter/Contents/Resources/schema.xml
/Users/me/Library/Spotlight/MyCustomImporter.mdimporter/Contents/Resources/schema.xml : succesfully parsed.
Your implementation of
GetMetadataForFile
is populating the dictionary with the correct metadata entries and is returningtrue
.You return only CFTypes of CFString, CFNumber, CFBoolean, and CFDate as attribute values. If an attribute is specified as multivalued, you must return a CFArray of the expected CFType.
What are the imported metadata attributes for a specific file?
You can determine the metadata attributes and values in the system store for a file by using the mdls
command:
mdls /Applications/iTunes.app |
/Applications/iTunes.app ------------- |
kMDItemAttributeChangeDate = 2005-01-16 03:03:14 -0500 |
kMDItemContentType = "com.apple.application-bundle" |
kMDItemContentTypeTree = ( |
"com.apple.application-bundle", |
"com.apple.application", |
"public.executable", |
"com.apple.bundle", |
"public.directory", |
"public.item", |
"com.apple.package" |
) |
kMDItemCopyright = "iTunes 4.7, Copyright 2000-2004 Apple Computer, Inc." |
kMDItemDisplayName = "iTunes" |
kMDItemFSContentChangeDate = 2005-01-08 18:17:52 -0500 |
kMDItemFSCreationDate = 2005-01-08 18:17:52 -0500 |
kMDItemFSCreatorCode = 0 |
kMDItemFSFinderFlags = 0 |
kMDItemFSInvisible = 0 |
kMDItemFSLabel = 0 |
kMDItemFSName = "iTunes.app" |
kMDItemFSNodeCount = 1 |
kMDItemFSOwnerGroupID = 80 |
kMDItemFSOwnerUserID = 0 |
kMDItemFSSize = 0 |
kMDItemFSTypeCode = 0 |
kMDItemID = 64286 |
kMDItemKind = "Application" |
kMDItemLastUsedDate = 2005-01-16 01:01:10 -0500 |
kMDItemUsedDates = ( |
2005-01-08 18:17:52 -0500, |
2005-01-13 19:00:00 -0500, |
2005-01-15 19:00:00 -0500 |
) |
kMDItemVersion = "4.7" |
You can also specify a specific metadata attribute to return the value of:
mdls -name kMDItemContentType /Applications/iTunes.app |
/Applications/iTunes.app ------------- |
kMDItemContentType = "com.apple.application-bundle" |
Why isn’t Spotlight finding my document bundles when they are saved by my application?
If your application saves its files as a bundle, you must take precautions to ensure that Spotlight doesn’t attempt to import your file bundle before all the data is written to the bundle.
See Spotlight and Document Bundles for additional details.
Copyright © 2004, 2013 Apple Inc. All Rights Reserved. Terms of Use | Privacy Policy | Updated: 2013-08-08