Created
April 16, 2025 20:58
-
-
Save jevinskie/56100a079c1c264d50f23a8af1ddf327 to your computer and use it in GitHub Desktop.
Spotlight Importer.xctemplate
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
//============================================================================== | |
// Core Data Application Spotlight Importer | |
//============================================================================== | |
Spotlight importers should be provided by all applications that support custom | |
document formats. A Spotlight importer parses your document format for relevant | |
information and assigning that information to the appropriate metadata keys. | |
The bundle target in this project creates a Spotlight importer bundle installed | |
inside of the wrapper of the application target. This bundle includes all of | |
the code necessary to import two types of information into Spotlight: | |
1) The metadata information from Core Data stores. | |
The only default metadata for a Core Data store is the store ID and store type, | |
neither of which is imported. To have metadata from your stores imported, you | |
must first add the information you are interested to the metadata for your | |
store (see the NSPersistentStoreCoordinator setMetadataForPersistentStore: API) | |
and then pull the information for import in the GetMetadataForFile function in | |
the 'GetMetadataForFile.c' file. | |
2) Instance Level indexing information | |
For each instance of an entity that contains properties indexed by Spotlight | |
(defined in your Core Data Model), the importer will extract the values. This | |
extraction is done in MySpotlightImporter.m | |
Additionally, the importer must contain a list of the Uniform Type Identifiers | |
(UTI) for your application in order to import the data. (The UTI information is | |
used by Spotlight to know which importer to invoke for a given file.) If the | |
UTI is not already registered by your application, you will need to register it | |
in the importer bundle. (For more information on registering UTIs for | |
applications, consult the documentation at http://developer.apple.com) | |
----------------------------------------------------------------------------- | |
To configure this project | |
Search for all occurrences of the string YOUR_ and replace with the appropriate | |
values | |
When importing store file metadata | |
YOUR_STORE_FILE_UTI - UTI of your store file | |
YOUR_INFO - metadata information you want Spotlight to have for | |
your store file | |
when importing record level information | |
YOUR_EXTERNAL_RECORD_UTI - UTI of the Core Data Spotlight external record file | |
YOUR_EXTERNAL_RECORD_EXTENSION - extension of the Core Data external record file | |
YOUR_STORE_TYPE - type of your persistent store | |
Replace occurrences of the above strings in the following files | |
GetMetadataForFile.c | |
MySpotlightImporter.m | |
Info.plist | |
----------------------------------------------------------------------------- |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// | |
// ___FILENAME___ | |
// ___PACKAGENAME___ | |
// | |
// Created by ___FULLUSERNAME___ on ___DATE___. | |
//___COPYRIGHT___ | |
// | |
#include <CoreFoundation/CoreFoundation.h> | |
#import <CoreData/CoreData.h> | |
#import "MySpotlightImporter.h" | |
Boolean GetMetadataForFile(void *thisInterface, CFMutableDictionaryRef attributes, CFStringRef contentTypeUTI, CFStringRef pathToFile); | |
//============================================================================== | |
// | |
// Get metadata attributes from document files | |
// | |
// The purpose of this function is to extract useful information from the | |
// file formats for your document, and set the values into the attribute | |
// dictionary for Spotlight to include. | |
// | |
//============================================================================== | |
Boolean GetMetadataForFile(void *thisInterface, CFMutableDictionaryRef attributes, CFStringRef contentTypeUTI, CFStringRef pathToFile) | |
{ | |
// Pull any available metadata from the file at the specified path | |
// Return the attribute keys and attribute values in the dict | |
// Return TRUE if successful, FALSE if there was no data provided | |
// The path could point to either a Core Data store file in which | |
// case we import the store's metadata, or it could point to a Core | |
// Data external record file for a specific record instances | |
Boolean ok = FALSE; | |
@autoreleasepool { | |
NSError *error = nil; | |
if ([(__bridge NSString *)contentTypeUTI isEqualToString:@"YOUR_STORE_FILE_UTI"]) { | |
// import from store file metadata | |
// Create the URL, then attempt to get the meta-data from the store | |
NSURL *url = [NSURL fileURLWithPath:(__bridge NSString *)pathToFile]; | |
// This uses NSXMLStoreType. If your store is a different type, specify the correct type here. | |
NSDictionary *metadata = [NSPersistentStoreCoordinator metadataForPersistentStoreOfType:YOUR_STORE_TYPE URL:url options:nil error:&error]; | |
// If there is no error, add the info | |
if (error == NULL) { | |
// Get the information you are interested in from the dictionary | |
// "YOUR_INFO" should be replaced by key(s) you are interested in | |
NSObject *contentToIndex = metadata[@"YOUR_INFO"]; | |
if (contentToIndex != nil) { | |
// Add the metadata to the text content for indexing | |
((__bridge NSMutableDictionary *)attributes)[(NSString *)kMDItemTextContent] = contentToIndex; | |
ok = TRUE; | |
} | |
} | |
} else if ([(__bridge NSString *)contentTypeUTI isEqualToString:@"YOUR_EXTERNAL_RECORD_UTI"]) { | |
// import from an external record file | |
MySpotlightImporter *importer = [[MySpotlightImporter alloc] init]; | |
ok = [importer importFileAtPath:(__bridge NSString *)pathToFile attributes:(__bridge NSMutableDictionary *)attributes error:&error]; | |
} | |
} | |
// Return the status | |
return ok; | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// | |
// ___FILENAME___ | |
// ___PACKAGENAME___ | |
// | |
// Created by ___FULLUSERNAME___ on ___DATE___. | |
//___COPYRIGHT___ | |
// | |
//============================================================================== | |
// | |
// DO NO MODIFY THE CONTENT OF THIS FILE | |
// | |
// This file contains the generic CFPlug-in code necessary for your importer | |
// To complete your importer implement the function in GetMetadataForFile.c | |
// | |
//============================================================================== | |
#import <CoreFoundation/CoreFoundation.h> | |
#import <CoreFoundation/CFPlugInCOM.h> | |
#import <CoreServices/CoreServices.h> | |
// ----------------------------------------------------------------------------- | |
// constants | |
// ----------------------------------------------------------------------------- | |
#define PLUGIN_ID "___UUID___" | |
// | |
// Below is the generic glue code for all plug-ins. | |
// | |
// You should not have to modify this code aside from changing | |
// names if you decide to change the names defined in the Info.plist | |
// | |
// ----------------------------------------------------------------------------- | |
// typedefs | |
// ----------------------------------------------------------------------------- | |
// The import function to be implemented in GetMetadataForFile.c | |
Boolean GetMetadataForFile(void *thisInterface, | |
CFMutableDictionaryRef attributes, | |
CFStringRef contentTypeUTI, | |
CFStringRef pathToFile); | |
// The layout for an instance of MetaDataImporterPlugIn | |
typedef struct __MetadataImporterPluginType | |
{ | |
MDImporterInterfaceStruct *conduitInterface; | |
CFUUIDRef factoryID; | |
UInt32 refCount; | |
} MetadataImporterPluginType; | |
// ----------------------------------------------------------------------------- | |
// prototypes | |
// ----------------------------------------------------------------------------- | |
// Forward declaration for the IUnknown implementation. | |
// | |
MetadataImporterPluginType *AllocMetadataImporterPluginType(CFUUIDRef inFactoryID); | |
void DeallocMetadataImporterPluginType(MetadataImporterPluginType *thisInstance); | |
HRESULT MetadataImporterQueryInterface(void *thisInstance,REFIID iid,LPVOID *ppv); | |
void *MetadataImporterPluginFactory(CFAllocatorRef allocator,CFUUIDRef typeID); | |
ULONG MetadataImporterPluginAddRef(void *thisInstance); | |
ULONG MetadataImporterPluginRelease(void *thisInstance); | |
// ----------------------------------------------------------------------------- | |
// testInterfaceFtbl definition | |
// ----------------------------------------------------------------------------- | |
// The TestInterface function table. | |
// | |
static MDImporterInterfaceStruct testInterfaceFtbl = { | |
NULL, | |
MetadataImporterQueryInterface, | |
MetadataImporterPluginAddRef, | |
MetadataImporterPluginRelease, | |
GetMetadataForFile | |
}; | |
// ----------------------------------------------------------------------------- | |
// AllocMetadataImporterPluginType | |
// ----------------------------------------------------------------------------- | |
// Utility function that allocates a new instance. | |
// You can do some initial setup for the importer here if you wish | |
// like allocating globals etc... | |
// | |
MetadataImporterPluginType *AllocMetadataImporterPluginType(CFUUIDRef inFactoryID) | |
{ | |
MetadataImporterPluginType *theNewInstance; | |
theNewInstance = (MetadataImporterPluginType *)malloc(sizeof(MetadataImporterPluginType)); | |
memset(theNewInstance,0,sizeof(MetadataImporterPluginType)); | |
/* Point to the function table */ | |
theNewInstance->conduitInterface = &testInterfaceFtbl; | |
/* Retain and keep an open instance refcount for each factory. */ | |
theNewInstance->factoryID = CFRetain(inFactoryID); | |
CFPlugInAddInstanceForFactory(inFactoryID); | |
/* This function returns the IUnknown interface so set the refCount to one. */ | |
theNewInstance->refCount = 1; | |
return theNewInstance; | |
} | |
// ----------------------------------------------------------------------------- | |
// Dealloc___PACKAGENAMEASIDENTIFIER___MDImporterPluginType | |
// ----------------------------------------------------------------------------- | |
// Utility function that deallocates the instance when | |
// the refCount goes to zero. | |
// In the current implementation importer interfaces are never deallocated | |
// but implement this as this might change in the future | |
// | |
void DeallocMetadataImporterPluginType(MetadataImporterPluginType *thisInstance) | |
{ | |
CFUUIDRef theFactoryID; | |
theFactoryID = thisInstance->factoryID; | |
free(thisInstance); | |
if (theFactoryID){ | |
CFPlugInRemoveInstanceForFactory(theFactoryID); | |
CFRelease(theFactoryID); | |
} | |
} | |
// ----------------------------------------------------------------------------- | |
// MetadataImporterQueryInterface | |
// ----------------------------------------------------------------------------- | |
// Implementation of the IUnknown QueryInterface function. | |
// | |
HRESULT MetadataImporterQueryInterface(void *thisInstance,REFIID iid,LPVOID *ppv) | |
{ | |
CFUUIDRef interfaceID; | |
interfaceID = CFUUIDCreateFromUUIDBytes(kCFAllocatorDefault,iid); | |
if (CFEqual(interfaceID,kMDImporterInterfaceID)){ | |
/* If the Right interface was requested, bump the ref count, | |
* set the ppv parameter equal to the instance, and | |
* return good status. | |
*/ | |
((MetadataImporterPluginType*)thisInstance)->conduitInterface->AddRef(thisInstance); | |
*ppv = thisInstance; | |
CFRelease(interfaceID); | |
return S_OK; | |
}else{ | |
if (CFEqual(interfaceID,IUnknownUUID)){ | |
/* If the IUnknown interface was requested, same as above. */ | |
((MetadataImporterPluginType*)thisInstance )->conduitInterface->AddRef(thisInstance); | |
*ppv = thisInstance; | |
CFRelease(interfaceID); | |
return S_OK; | |
}else{ | |
/* Requested interface unknown, bail with error. */ | |
*ppv = NULL; | |
CFRelease(interfaceID); | |
return E_NOINTERFACE; | |
} | |
} | |
} | |
// ----------------------------------------------------------------------------- | |
// MetadataImporterPluginAddRef | |
// ----------------------------------------------------------------------------- | |
// Implementation of reference counting for this type. Whenever an interface | |
// is requested, bump the refCount for the instance. NOTE: returning the | |
// refcount is a convention but is not required so don't rely on it. | |
// | |
ULONG MetadataImporterPluginAddRef(void *thisInstance) | |
{ | |
((MetadataImporterPluginType *)thisInstance )->refCount += 1; | |
return ((MetadataImporterPluginType*) thisInstance)->refCount; | |
} | |
// ----------------------------------------------------------------------------- | |
// SampleCMPluginRelease | |
// ----------------------------------------------------------------------------- | |
// When an interface is released, decrement the refCount. | |
// If the refCount goes to zero, deallocate the instance. | |
// | |
ULONG MetadataImporterPluginRelease(void *thisInstance) | |
{ | |
((MetadataImporterPluginType*)thisInstance)->refCount -= 1; | |
if (((MetadataImporterPluginType*)thisInstance)->refCount == 0){ | |
DeallocMetadataImporterPluginType((MetadataImporterPluginType*)thisInstance ); | |
return 0; | |
}else{ | |
return ((MetadataImporterPluginType*) thisInstance )->refCount; | |
} | |
} | |
// ----------------------------------------------------------------------------- | |
// ___PACKAGENAMEASIDENTIFIER___MDImporterPluginFactory | |
// ----------------------------------------------------------------------------- | |
// Implementation of the factory function for this type. | |
// | |
void *MetadataImporterPluginFactory(CFAllocatorRef allocator,CFUUIDRef typeID) | |
{ | |
MetadataImporterPluginType *result; | |
CFUUIDRef uuid; | |
/* If correct type is being requested, allocate an | |
* instance of TestType and return the IUnknown interface. | |
*/ | |
if (CFEqual(typeID,kMDImporterTypeID)){ | |
uuid = CFUUIDCreateFromString(kCFAllocatorDefault,CFSTR(PLUGIN_ID)); | |
result = AllocMetadataImporterPluginType(uuid); | |
CFRelease(uuid); | |
return result; | |
} | |
/* If the requested type is incorrect, return NULL. */ | |
return NULL; | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// | |
// ___FILENAME___ | |
// ___PACKAGENAME___ | |
// | |
// Created by ___FULLUSERNAME___ on ___DATE___. | |
//___COPYRIGHT___ | |
// | |
#import <Cocoa/Cocoa.h> | |
#define YOUR_STORE_TYPE NSXMLStoreType | |
@interface MySpotlightImporter : NSObject | |
@property (readonly, strong, nonatomic) NSPersistentStoreCoordinator *persistentStoreCoordinator; | |
@property (readonly, strong, nonatomic) NSManagedObjectModel *managedObjectModel; | |
@property (readonly, strong, nonatomic) NSManagedObjectContext *managedObjectContext; | |
- (BOOL)importFileAtPath:(NSString *)filePath attributes:(NSMutableDictionary *)attributes error:(NSError **)error; | |
@end |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// | |
// ___FILENAME___ | |
// ___PACKAGENAME___ | |
// | |
// Created by ___FULLUSERNAME___ on ___DATE___. | |
//___COPYRIGHT___ | |
// | |
#import "MySpotlightImporter.h" | |
@interface MySpotlightImporter () | |
@property (nonatomic, strong) NSURL *modelURL; | |
@property (nonatomic, strong) NSURL *storeURL; | |
@end | |
@implementation MySpotlightImporter | |
@synthesize persistentStoreCoordinator = _persistentStoreCoordinator; | |
@synthesize managedObjectModel = _managedObjectModel; | |
@synthesize managedObjectContext = _managedObjectContext; | |
- (BOOL)importFileAtPath:(NSString *)filePath attributes:(NSMutableDictionary *)spotlightData error:(NSError **)error | |
{ | |
NSDictionary *pathInfo = [NSPersistentStoreCoordinator elementsDerivedFromExternalRecordURL:[NSURL fileURLWithPath:filePath]]; | |
self.modelURL = [NSURL fileURLWithPath:[pathInfo valueForKey:NSModelPathKey]]; | |
self.storeURL = [NSURL fileURLWithPath:[pathInfo valueForKey:NSStorePathKey]]; | |
NSURL *objectURI = [pathInfo valueForKey:NSObjectURIKey]; | |
NSManagedObjectID *oid = [[self persistentStoreCoordinator] managedObjectIDForURIRepresentation:objectURI]; | |
if (!oid) { | |
NSLog(@"%@:%@ to find object id from path %@", [self class], NSStringFromSelector(_cmd), filePath); | |
return NO; | |
} | |
NSManagedObject *instance = [[self managedObjectContext] objectWithID:oid]; | |
// how you process each instance will depend on the entity that the instance belongs to | |
if ([[[instance entity] name] isEqualToString:@"YOUR_ENTITY_NAME"]) { | |
// set the display name for Spotlight search result | |
NSString *yourDisplayString = [NSString stringWithFormat:@"YOUR_DISPLAY_STRING %@", [instance valueForKey:@"SOME_KEY"]]; | |
spotlightData[(NSString *)kMDItemDisplayName] = yourDisplayString; | |
/* | |
Determine how you want to store the instance information in 'spotlightData' dictionary. | |
For each property, pick the key kMDItem... from MDItem.h that best fits its content. | |
If appropriate, aggregate the values of multiple properties before setting them in the dictionary. | |
For relationships, you may want to flatten values. | |
id YOUR_FIELD_VALUE = [instance valueForKey:ATTRIBUTE_NAME]; | |
spotlightData[(NSString *) kMDItem...] = YOUR_FIELD_VALUE; | |
... more property values; | |
To determine if a property should be indexed, call isIndexedBySpotlight | |
*/ | |
} | |
return YES; | |
} | |
static NSURL *cachedModelURL = nil; | |
static NSManagedObjectModel *cachedModel = nil; | |
static NSDate *cachedModelModificationDate =nil; | |
// Returns the managed object model. The last read model is cached in a global variable and reused if the URL and modification date are identical | |
- (NSManagedObjectModel *)managedObjectModel | |
{ | |
if (_managedObjectModel != nil) | |
return _managedObjectModel; | |
NSDictionary *modelFileAttributes = [[NSFileManager defaultManager] attributesOfItemAtPath:[self.modelURL path] error:nil]; | |
NSDate *modelModificationDate = modelFileAttributes[NSFileModificationDate]; | |
if ([cachedModelURL isEqual:self.modelURL] && [modelModificationDate isEqualToDate:cachedModelModificationDate]) { | |
_managedObjectModel = cachedModel; | |
} | |
if (!_managedObjectModel) { | |
_managedObjectModel = [[NSManagedObjectModel alloc] initWithContentsOfURL:self.modelURL]; | |
if (!_managedObjectModel) { | |
NSLog(@"%@:%@ unable to load model at URL %@", [self class], NSStringFromSelector(_cmd), self.modelURL); | |
return nil; | |
} | |
// Clear out all custom classes used by the model to avoid having to link them | |
// with the importer. Remove this code if you need to access your custom logic. | |
NSString *managedObjectClassName = [NSManagedObject className]; | |
for (NSEntityDescription *entity in _managedObjectModel) { | |
[entity setManagedObjectClassName:managedObjectClassName]; | |
} | |
// cache last loaded model | |
cachedModelURL = self.modelURL; | |
cachedModel = _managedObjectModel; | |
cachedModelModificationDate = modelModificationDate; | |
} | |
return _managedObjectModel; | |
} | |
// Returns the persistent store coordinator for the importer. | |
- (NSPersistentStoreCoordinator *)persistentStoreCoordinator | |
{ | |
if (_persistentStoreCoordinator) | |
return _persistentStoreCoordinator; | |
NSError *error = nil; | |
_persistentStoreCoordinator = [[NSPersistentStoreCoordinator alloc] initWithManagedObjectModel:[self managedObjectModel]]; | |
if (![_persistentStoreCoordinator addPersistentStoreWithType:YOUR_STORE_TYPE configuration:nil URL:self.storeURL options:nil error:&error]) { | |
NSLog(@"%@:%@ unable to add persistent store coordinator - %@", [self class], NSStringFromSelector(_cmd), error); | |
} | |
return _persistentStoreCoordinator; | |
} | |
// Returns the managed object context for the importer; already bound to the persistent store coordinator. | |
- (NSManagedObjectContext *)managedObjectContext | |
{ | |
if (_managedObjectContext) | |
return _managedObjectContext; | |
NSPersistentStoreCoordinator *coordinator = [self persistentStoreCoordinator]; | |
if (!coordinator) { | |
NSLog(@"%@:%@ unable to get persistent store coordinator", [self class], NSStringFromSelector(_cmd)); | |
return nil; | |
} | |
_managedObjectContext = [[NSManagedObjectContext alloc] initWithConcurrencyType:NSMainQueueConcurrencyType]; | |
[_managedObjectContext setPersistentStoreCoordinator:coordinator]; | |
return _managedObjectContext; | |
} | |
@end |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?xml version="1.0" encoding="UTF-8"?> | |
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> | |
<plist version="1.0"> | |
<dict> | |
<key>Kind</key> | |
<string>Xcode.Xcode3.ProjectTemplateUnitKind</string> | |
<key>Identifier</key> | |
<string>com.apple.dt.unit.spotlightImporter</string> | |
<key>Ancestors</key> | |
<array> | |
<string>com.apple.dt.unit.systemPlugInBase</string> | |
</array> | |
<key>Concrete</key> | |
<true/> | |
<key>Description</key> | |
<string>This template builds a Core Data Spotlight Importer.</string> | |
<key>AssociatedTargetSpecification</key> | |
<dict> | |
<key>PopUpTitle</key> | |
<string>Embed in Application:</string> | |
<key>PopUpDescription</key> | |
<string>The application target that will host this new importer. The application will be set up to embed the new importer.</string> | |
<key>AllowableProductTypes</key> | |
<array> | |
<string>com.apple.product-type.application</string> | |
</array> | |
<key>AllowablePlatforms</key> | |
<array> | |
<string>com.apple.platform.macosx</string> | |
</array> | |
<key>AssociatedTargetIsDependent</key> | |
<true/> | |
<key>AssociatedTargetNeedsProductBuildPhaseInjection</key> | |
<true/> | |
</dict> | |
<key>Targets</key> | |
<array> | |
<dict> | |
<key>ProductType</key> | |
<string>com.apple.product-type.spotlight-importer</string> | |
<key>TargetIdentifier</key> | |
<string>com.apple.dt.cocoaSpotlightImporterTarget</string> | |
<key>SharedSettings</key> | |
<dict> | |
<key>INSTALL_PATH</key> | |
<string>@executable_path/../Contents/Library/Spotlight</string> | |
<key>SKIP_INSTALL</key> | |
<string>YES</string> | |
<key>WRAPPER_EXTENSION</key> | |
<string>mdimporter</string> | |
<key>ALWAYS_SEARCH_USER_PATHS</key> | |
<string>YES</string> | |
<key>LIBRARY_STYLE</key> | |
<string>BUNDLE</string> | |
</dict> | |
<key>BuildPhases</key> | |
<array> | |
<dict> | |
<key>Class</key> | |
<string>Sources</string> | |
</dict> | |
<dict> | |
<key>Class</key> | |
<string>Frameworks</string> | |
</dict> | |
<dict> | |
<key>Class</key> | |
<string>Resources</string> | |
</dict> | |
</array> | |
</dict> | |
</array> | |
<key>Nodes</key> | |
<array> | |
<string>main.c</string> | |
<string>GetMetadataForFile.m</string> | |
<string>MySpotlightImporter.h</string> | |
<string>MySpotlightImporter.m</string> | |
<string>Info.plist:spotlight</string> | |
<string>Info.plist:NSHumanReadableCopyright</string> | |
<string>Importer Read Me.txt</string> | |
</array> | |
<key>Definitions</key> | |
<dict> | |
<key>main.c</key> | |
<dict> | |
<key>Path</key> | |
<string>main.c</string> | |
<key>Group</key> | |
<string>Supporting Files</string> | |
</dict> | |
<key>GetMetadataForFile.m</key> | |
<dict> | |
<key>Path</key> | |
<string>GetMetadataForFile.m</string> | |
</dict> | |
<key>MySpotlightImporter.h</key> | |
<dict> | |
<key>Path</key> | |
<string>MySpotlightImporter.h</string> | |
</dict> | |
<key>MySpotlightImporter.m</key> | |
<dict> | |
<key>Path</key> | |
<string>MySpotlightImporter.m</string> | |
</dict> | |
<key>Info.plist:spotlight</key> | |
<string><![CDATA[<!-- | |
If your application does not already define a UTI, you may want to declare it | |
here, so that your documents are recognized by systems which do not have your | |
application installed. | |
To export this declaration, fill in the fields with your application's | |
information, and uncomment the block of XML. | |
--> | |
<key>UTExportedTypeDeclarations</key> | |
<array> | |
<dict> | |
<key>UTTypeIdentifier</key> | |
<string>YOUR_EXTERNAL_RECORD_UTI</string> | |
<key>UTTypeReferenceURL</key> | |
<string>http://www.company.com/yourproduct</string> | |
<key>UTTypeDescription</key> | |
<string>Your Document Kind String</string> | |
<key>UTTypeConformsTo</key> | |
<array> | |
<string>public.data</string> | |
<string>public.content</string> | |
</array> | |
<key>UTTypeTagSpecification</key> | |
<dict> | |
<key>com.apple.ostype</key> | |
<string>XXXX</string> | |
<key>public.filename-extension</key> | |
<array> | |
<string>YOUR_EXTERNAL_RECORD_EXTENSION</string> | |
</array> | |
</dict> | |
</dict> | |
</array> | |
<key>CFBundleDocumentTypes</key> | |
<array> | |
<dict> | |
<key>CFBundleTypeRole</key> | |
<string>MDImporter</string> | |
<key>LSItemContentTypes</key> | |
<array> | |
<string>YOUR_EXTERNAL_RECORD_UTI</string> | |
</array> | |
</dict> | |
</array> | |
<key>CFPlugInDynamicRegisterFunction</key> | |
<string></string> | |
<key>CFPlugInDynamicRegistration</key> | |
<string>NO</string> | |
<key>CFPlugInFactories</key> | |
<dict> | |
<key>___UUID___</key> | |
<string>MetadataImporterPluginFactory</string> | |
</dict> | |
<key>CFPlugInTypes</key> | |
<dict> | |
<key>8B08C4BF-415B-11D8-B3F9-0003936726FC</key> | |
<array> | |
<string>___UUID___</string> | |
</array> | |
</dict> | |
<key>CFPlugInUnloadFunction</key> | |
<string></string> | |
<key>LSMinimumSystemVersion</key> | |
<string>$(MACOSX_DEPLOYMENT_TARGET)</string> | |
]]></string> | |
<key>Importer Read Me.txt</key> | |
<dict> | |
<key>Path</key> | |
<string>Importer Read Me.txt</string> | |
<key>TargetIdentifiers</key> | |
<array/> | |
</dict> | |
</dict> | |
</dict> | |
</plist> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment