I have a macOS application that stores text as an HTML file inside a package (directory bundle). The system Rich Text importer already knows how to extract text from HTML files. Is there a way to write an importer for my application that calls the Rich Text importer on the HTML file? I can see from the Spotlight Importer boilerplate code that it is being invoked as a COM plugin, but it is not obvious how to invoke it from my importer.
Asked
Active
Viewed 75 times
1 Answers
1
I figured out how to do it:
#include <CoreFoundation/CoreFoundation.h>
#include <CoreServices/CoreServices.h>
#include <CoreFoundation/CFPlugInCom.h>
Boolean GetMetadataForFile(void *thisInterface,
CFMutableDictionaryRef attributes,
CFStringRef contentTypeUTI,
CFStringRef pathToFile);
Boolean getMetadataFromRichTextFile(CFMutableDictionaryRef attributes,
CFStringRef contentTypeUTI,
CFStringRef pathToFile)
{
CFURLRef url = CFURLCreateWithFileSystemPath(NULL, CFSTR("/System/Library/Spotlight/RichText.mdimporter"), kCFURLPOSIXPathStyle, TRUE);
CFPlugInRef plugin = CFPlugInCreate(NULL, url);
Boolean result = FALSE;
if (!plugin) {
printf("Unable to load RichText importer\n");
} else {
CFArrayRef factories = CFPlugInFindFactoriesForPlugInTypeInPlugIn(kMDImporterTypeID, plugin);
if ((factories != NULL) && (CFArrayGetCount(factories) > 0)) {
CFUUIDRef factoryID = CFArrayGetValueAtIndex(factories, 0);
IUnknownVTbl **iunknown = CFPlugInInstanceCreate(NULL, factoryID, kMDImporterTypeID);
if (iunknown) {
MDImporterInterfaceStruct **interface = NULL;
(*iunknown)->QueryInterface(iunknown, CFUUIDGetUUIDBytes(kMDImporterInterfaceID), (LPVOID *)(&interface));
(*iunknown)->Release(iunknown);
if (interface) {
(*interface)->ImporterImportData(interface, attributes, contentTypeUTI, pathToFile);
(*interface)->Release(interface);
result = TRUE;
} else {
printf("Failed to get MDImporter interface.\n");
}
} else {
printf("Failed to create RichText importer instance.\n");
}
} else {
printf("Could not find RichText importer factory.\n");
}
CFRelease(plugin);
}
return result;
}
Boolean GetMetadataForFile(void *thisInterface,
CFMutableDictionaryRef attributes,
CFStringRef contentTypeUTI,
CFStringRef pathToFile)
{
Boolean result = FALSE;
@autoreleasepool {
CFStringRef path = CFStringCreateWithFormat(NULL, NULL, CFSTR("%@/index.html"), pathToFile);
result = getMetadataFromRichTextFile(attributes, kUTTypeHTML, path);
}
return result;
}

Alan Snyder
- 408
- 2
- 13
-
It would be a good idea to mark your answer as answered (the ✔ next to it) – TT. Oct 31 '18 at 12:12