oreilly.comSafari Books Online.Conferences.


AddThis Social Bookmark Button

Programming with Spotlight
Pages: 1, 2, 3, 4

Examine a Specific File's Metadata

Out next topic investigates Spotlight's ability to examine a specific file's metadata, and it's surprisingly easy. To illustrate, let's enhance our example project. For the sake of time, we'll stay focused and add a text view object that displays the metadata for a specific file. In your own applications, you'd probably be doing something more involved. You can find plenty of good Cocoa tutorials that illustrate broader topics involving user interaction, file browsers, etc. here on MacDevCenter if you need that additional context.

Modify your controller files (changes are in bold):

For "Controller.h":

//  Controller.h
//  SpotlightExamples

#import <Cocoa/Cocoa.h>

@interface Controller : NSObject {
    IBOutlet NSButton* openSearchWindowButton;    

    IBOutlet NSTextView* metadataInfoView;
    IBOutlet NSButton* displayMetadataButton;

- (IBAction)openSearchWindowAction:(id)sender;

- (IBAction)displayMetadataAction:(id)sender;


For "Controller.m":

//  Controller.m
//  SpotlightExamples

#import "Controller.h"

@implementation Controller

- (IBAction)openSearchWindowAction:(id)sender
    OSStatus resultCode=noErr;
    //Replace "Search Text" with user input
    resultCode=HISearchWindowShow((CFStringRef)@"Search Text", kNilOptions);
    if (resultCode != noErr) {
        NSLog(@"Failed to open search window");
        //Could use NSAlert class to display interactive dialog

- (IBAction)displayMetadataAction:(id)sender
    //create a CF-compliant object representing a file and its metadata using
    //a Carbon level call
    //add in a path to an existing file on your system
    CFStringRef path = CFSTR("/Users/matthew/temp.txt");
    MDItemRef item = MDItemCreate(kCFAllocatorDefault, path);
    //pull out the metadata attribute names
    CFArrayRef attributeNames = MDItemCopyAttributeNames(item);
    //use toll-free bridging to load up an NSArray for convenience
    NSArray* array = (NSArray*)attributeNames;
    NSEnumerator *e = [array objectEnumerator];
    id arrayObject;
    NSMutableString *info = [NSMutableString stringWithCapacity:50];
    CFTypeRef ref;
    while ((arrayObject = [e nextObject]))
        ref = 
        MDItemCopyAttribute(item, (CFStringRef)[arrayObject description]);
        //cast to get an NSObject for convenience
        NSObject* tempObject = (NSObject*)ref;
        [info appendString:[arrayObject description]];
        [info appendString:@" = "];
        [info appendString:[tempObject description]];
        [info appendString:@"\n"];
    //set the info in the text view
    [metadataInfoView insertText:info];

You'll need to update your instantiated controller to reflect changes in your source code by dragging the "Controller.h" file onto the main Interface Builder palette and choose to "Replace" when prompted. Without this change, the controller won't recognize the new outlets and action you just added.

  • Spruce up your application's main window in Interface Builder
    • Add an NSButton and rename it "Display Metadata"
    • Add an NSTextView (from the "Cocoa-Text" tab)
    • Set the outlet and action for the new button
    • Set the outlet for the text view the same as with the button (it doesn't have any actions)

With all that done, ensure that you've specified a file that exists on your system in method openSearchWindowAction:. I just created a temporary text file for purposes of illustration. Again, your application would be doing all sorts of fancy user interaction here; we're being simple on purpose. "Build and Go" to see the action. If something's not working, double check your outlets and connections. You can always add NSLog messages to help troubleshoot.

Your project is now capable of examining a file's metadata.

You can get the project file for this second portion here.

Pages: 1, 2, 3, 4

Next Pagearrow