Search code examples
objective-cxcodemacoscocoaiphoto

Read from iPhoto Library programmatically


I want to create an Application that connects to the iPhoto Library. So now I would like to read the Events and the pictures themselves from the library.

Is there an elegant / easy way to do this or do I have to manually read the Bundle Structure of the iPhoto User Data?

So far I have only found a picture taker: Is there a UIImagePicker for the Mac Desktop

Update: I found another relevant SO post: Selecting iPhoto images within a cocoa application


Solution

  • You can do it with NSAppleScript. This is some copy/paste from my app, hacked up a bit just to show the idea.

        NSAppleEventDescriptor d = .. compile this script ..
            @"tell application \"iPhoto\" to properties of albums"
    
        for (int i = 0; i < [d numberOfItems]; i++)
        {
            NSAppleEventDescriptor *albumDesc = [d descriptorAtIndex:i];
    
            // <NSAppleEventDescriptor: 'ipal'{ 
            //  'ID  ':4.265e+09, 
            //  'purl':'utxt'("http://www.flickr.com/photos/..."), 
            //  'pnam':'utxt'("Vacation"), 
            //  'alTy':'pubs', 
            //  'alCh':[  ], 
            //  'alPx':'msng' }>
    
            NSString *albumName = [[albumDesc descriptorForKeyword:'pnam'] stringValue];
            NSString *albumId = [[albumDesc descriptorForKeyword:'ID  '] stringValue];
    

    You can do the same thing to find the images

    NSString *scp = 
        [NSString stringWithFormat:@"tell application \"iPhoto\" to properties of photos of album id %@",
         [album objectForKey:@"id"]];
    
    NSAppleEventDescriptor *d = ... compile scp ...
    
    // 1 based!?
    for (int i = 1; i <= [d numberOfItems]; i++)
    {
        NSAppleEventDescriptor *photoDesc = [d descriptorAtIndex:i];
    
        // Yes.. this happens.  Not sure why?!
        if (!photoDesc)
            continue;
    
        // <NSAppleEventDescriptor: 'ipmr'{ 
        // 'pnam':'utxt'("IMG_0058.JPG"), 
        // 'pwid':768, 
        // 'pdim':[ 768, 1024 ], 
        // 'alti':1.79769e+308, 
        // 'filn':'utxt'("3133889525_10975ba071_b.jpg"), 
        // 'ipth':'utxt'("/Users/lagnat/Pictures/iPhoto Library/Masters/2010/11/10/20101110-002341/3133889525_10975ba071_b.jpg"), 
        // 'idat':'ldt '($F57C69C500000000$), 
        // 'rate':0, 
        // 'titl':'utxt'("IMG_0058.JPG"), 
        // 'phit':1024, 
        // 'itpt':'utxt'("/Users/lagnat/Pictures/iPhoto Library/Thumbnails/2010/11/10/20101110-002341/3133889525_10975ba071_b.jpg.jpg"), 
        // 'ID  ':4.295e+09, 
        // 'lati':'msng', 
        // 'pcom':'utxt'(""), 
        // 'opth':'utxt'("/Users/lagnat/Pictures/iPhoto Library/Masters/2010/11/10/20101110-002341/3133889525_10975ba071_b.jpg"), 
        // 'lngt':'msng', 
        // 'tiln':'utxt'("3133889525_10975ba071_b.jpg.jpg") }>
    
        NSString *path = [[photoDesc descriptorForKeyword:'ipth'] stringValue];
        NSString *imgname = [[photoDesc descriptorForKeyword:'pnam'] stringValue];