【问题标题】:Read from iPhoto Library programmatically以编程方式从 iPhoto 库中读取
【发布时间】:2019-01-03 14:38:33
【问题描述】:

我想创建一个连接到 iPhoto 图库的应用程序。所以现在我想从图书馆阅读活动和图片本身。

是否有一种优雅/简单的方法可以做到这一点,还是我必须手动读取 iPhoto 用户数据的捆绑结构?

目前我只找到了一个拍照者:Is there a UIImagePicker for the Mac Desktop

更新:我发现了另一个相关的 SO 帖子:Selecting iPhoto images within a cocoa application

【问题讨论】:

    标签: objective-c xcode macos cocoa iphoto


    【解决方案1】:

    您可以使用 NSAppleScript 来完成。这是我的应用程序中的一些复制/粘贴,只是为了展示这个想法而稍作修改。

        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];
    

    你可以做同样的事情来查找图像

    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];
    

    【讨论】:

      【解决方案2】:

      如果在 App Store 上发布应用程序,您现在需要使用沙盒,这会使之前的 AppleScript 方法停止工作(iPhoto 应用程序启动但返回一个空集)。

      iPhoto 库由包含照片、数据库和 XML 文件的目录结构组成。内容随 iPhoto 的每个版本而变化,因此手动访问这些文件时要小心。

      如果您只需要专辑详细信息,您可以解析文件 AlbumData.xml

      如果您想要照片,可以浏览 Masters 文件夹。文件结构遵循日期而不是 iPhoto 中配置的集合。

      可以在此处找到有关 iPhoto 库内部的更多信息: http://www.fatcatsoftware.com/iplm/Help/iphoto%20library%20internals.html

      大多数数据库都是 SQLite 格式,因此可以通过 Objective C 以编程方式访问,尽管您可以再次预期不同版本的 iPhoto 之间的架构更改。感兴趣的主要数据库是 Database/apdb 中的 Library.apdb 和 Properties.apdb。


      如果您仍想使用 Apple Script 方法,这里是先前答案的一个版本,其中包含 Apple 脚本执行部分:

      NSAppleScript *script = [[NSAppleScript alloc] initWithSource:@"tell application \"iPhoto\" to properties of albums"];
      NSAppleEventDescriptor *d = [script executeAndReturnError:nil];
      
      NSLog(@"photo library count: %ld", (long)[d numberOfItems]);
      
      for (int i = 0; i < [d numberOfItems]; i++)
      {
          NSAppleEventDescriptor *albumDesc = [d descriptorAtIndex:i];
      
          NSString *albumName = [[albumDesc descriptorForKeyword:'pnam'] stringValue];
          NSLog(@"%@", albumName);
      }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2011-11-16
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2010-09-28
        • 1970-01-01
        相关资源
        最近更新 更多