我想创建一个连接到 iPhoto 库的应用程序。所以现在我想从图书馆阅读活动和图片本身。
有没有一种优雅/简单的方法可以做到这一点,还是我必须手动读取 iPhoto 用户数据的捆绑结构?
到目前为止,我只找到了一个拍照者:Mac Desktop 有 UIImagePicker
更新:我发现了另一个相关的 SO 帖子:在可可应用程序中选择 iPhoto 图像
我想创建一个连接到 iPhoto 库的应用程序。所以现在我想从图书馆阅读活动和图片本身。
有没有一种优雅/简单的方法可以做到这一点,还是我必须手动读取 iPhoto 用户数据的捆绑结构?
到目前为止,我只找到了一个拍照者:Mac Desktop 有 UIImagePicker
更新:我发现了另一个相关的 SO 帖子:在可可应用程序中选择 iPhoto 图像
您可以使用 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];
如果在 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);
}