iFotobilder will be an iPhoto export plugin that will let you manage your Fotobilder pictures through iPhoto.

## Getting Started

Since iPhoto's APIs aren't public, and because my Objective C is extremely rusty, I wanted a couple of examples of other people's plugins before I dove into this.

Here's what I found:

* [Writing Plugins for Cocoa][1]

[1]: http://www.stone.com/The_Cocoa_Files/Writing_PlugIns.html

## The iPhoto Export API

Using the `class-dump` tool, I dumped the export API: 

	/*
	 *     Generated by class-dump 3.0.
	 *
	 *     class-dump is Copyright (C) 1997-1998, 2000-2001, 2004 by Steve Nygard.
	 */
	
	/*
	 * File: /Applications/iPhoto.app/Contents/MacOS/iPhoto
	 */
	
	@protocol ExportImageProtocol
	- (unsigned int)imageCount;
	- (BOOL)imageIsPortraitAtIndex:(unsigned int)fp20;
	- (struct _NSSize)imageSizeAtIndex:(unsigned int)fp16;
	- (unsigned int)imageFormatAtIndex:(unsigned int)fp16;
	- (id)imageCaptionAtIndex:(unsigned int)fp16;
	- (id)imagePathAtIndex:(unsigned int)fp16;
	- (id)thumbnailPathAtIndex:(unsigned int)fp16;
	- (id)imageDictionaryAtIndex:(unsigned int)fp16;
	- (float)imageAspectRatioAtIndex:(unsigned int)fp16;
	- (id)albumName;
	- (id)albumMusicPath;
	- (unsigned int)albumCount;
	- (unsigned int)albumPositionOfImageAtIndex:(unsigned int)fp16;
	- (id)window;
	- (void)enableControls;
	- (void)disableControls;
	- (void)clickExport;
	- (void)startExport;
	- (void)cancelExport;
	- (void)cancelExportBeforeBeginning;
	- (id)directoryPath;
	- (id)temporaryDirectory;
	- (BOOL)doesFileExist:(id)fp16;
	- (BOOL)doesDirectoryExist:(id)fp16;
	- (BOOL)createDir:(id)fp16;
	- (id)uniqueSubPath:(id)fp12 child:(id)fp20;
	- (id)makeUniquePath:(id)fp16;
	- (id)makeUniqueFilePath:(id)fp12 extension:(id)fp20;
	- (id)makeUniqueFileNameWithTime:(id)fp16;
	- (BOOL)makeFSSpec:(id)fp12 spec:(struct FSSpec *)fp20;
	- (id)pathForFSSpec:(id)fp16;
	- (BOOL)getFSRef:(struct FSRef *)fp12 forPath:(id)fp16 isDirectory:(BOOL)fp27;
	- (id)pathForFSRef:(struct FSRef *)fp16;
	- (unsigned long)countFiles:(id)fp12 descend:(BOOL)fp23;
	- (unsigned long)countFilesFromArray:(id)fp12 descend:(BOOL)fp23;
	- (unsigned long long)sizeAtPath:(id)fp12 count:(unsigned long *)fp16 physical:(BOOL)fp27;
	- (BOOL)isAliasFileAtPath:(id)fp16;
	- (id)pathContentOfAliasAtPath:(id)fp16;
	- (id)stringByResolvingAliasesInPath:(id)fp16;
	- (BOOL)ensurePermissions:(unsigned long)fp12 forPath:(id)fp20;
	- (id)validFilename:(id)fp16;
	- (id)getExtensionForImageFormat:(unsigned int)fp16;
	- (unsigned int)getImageFormatForExtension:(id)fp16;
	- (struct OpaqueGrafPtr *)uncompressImage:(id)fp12 size:(struct _NSSize)fp16 pixelFormat:(unsigned int)fp24 rotation:(float)fp32;
	- (void *)createThumbnailer;
	- (void *)retainThumbnailer:(void *)fp16;
	- (void *)autoreleaseThumbnailer:(void *)fp16;
	- (void)releaseThumbnailer:(void *)fp16;
	- (void)setThumbnailer:(void *)fp16 maxBytes:(unsigned int)fp20 maxWidth:(unsigned int)fp24 maxHeight:(unsigned int)fp32;
	- (struct _NSSize)thumbnailerMaxBounds:(void *)fp16;
	- (void)setThumbnailer:(void *)fp12 quality:(int)fp20;
	- (int)thumbnailerQuality:(void *)fp16;
	- (void)setThumbnailer:(void *)fp12 rotation:(float)fp20;
	- (float)thumbnailerRotation:(void *)fp16;
	- (void)setThumbnailer:(void *)fp12 outputFormat:(unsigned int)fp20;
	- (unsigned int)thumbnailerOutputFormat:(void *)fp16;
	- (void)setThumbnailer:(void *)fp12 outputExtension:(id)fp20;
	- (id)thumbnailerOutputExtension:(void *)fp16;
	- (BOOL)thumbnailer:(void *)fp16 createThumbnail:(id)fp20 dest:(id)fp28;
	- (struct _NSSize)lastImageSize:(void *)fp20;
	- (struct _NSSize)lastThumbnailSize:(void *)fp16;
	@end
	
	@protocol ExportPluginBoxProtocol
	- (BOOL)performKeyEquivalent:(id)fp16;
	@end
	
	@protocol ExportPluginProtocol
	- (id)initWithExportImageObj:(id)fp16;
	- (id)settingsView;
	- (id)firstView;
	- (id)lastView;
	- (void)viewWillBeActivated;
	- (void)viewWillBeDeactivated;
	- (id)requiredFileType;
	- (BOOL)wantsDestinationPrompt;
	- (id)getDestinationPath;
	- (id)defaultFileName;
	- (id)defaultDirectory;
	- (BOOL)treatSingleSelectionDifferently;
	- (BOOL)validateUserCreatedPath:(id)fp16;
	- (void)clickExport;
	- (void)startExport:(id)fp16;
	- (void)performExport:(id)fp16;
	- (CDAnonymousStruct12 *)progress;
	- (void)lockProgress;
	- (void)unlockProgress;
	- (void)cancelExport;
	- (id)name;
	- (id)description;
	@end
	
	@interface ExportController : NSObject
	{
	    id mWindow;
	    id mExportView;
	    id mExportButton;
	    id mImageCount;
	    ExportMgr *mExportMgr;
	    ExportMgrRec *mCurrentPluginRec;
	    ProgressController *mProgressController;
	    BOOL mCancelExport;
	    NSTimer *mTimer;
	    NSString *mDirectoryPath;
	}
	
	- (void)awakeFromNib;
	- (void)dealloc;
	- (id)currentPlugin;
	- (id)currentPluginRec;
	- (void)setCurrentPluginRec:(id)fp12;
	- (id)directoryPath;
	- (void)setDirectoryPath:(id)fp12;
	- (void)show;
	- (void)_openPanelDidEnd:(id)fp12 returnCode:(int)fp16 contextInfo:(void *)fp20;
	- (id)panel:(id)fp12 userEnteredFilename:(id)fp16 confirmed:(BOOL)fp20;
	- (BOOL)panel:(id)fp12 shouldShowFilename:(id)fp16;
	- (BOOL)panel:(id)fp12 isValidFilename:(id)fp16;
	- (BOOL)filesWillFitOnDisk;
	- (void)export:(id)fp12;
	- (void)_exportThread:(id)fp12;
	- (void)_exportProgress:(id)fp12;
	- (void)startExport:(id)fp12;
	- (void)finishExport;
	- (void)cancelExport;
	- (void)cancel:(id)fp12;
	- (void)enableControls;
	- (id)window;
	- (void)disableControls;
	- (void)tabView:(id)fp12 willSelectTabViewItem:(id)fp16;
	- (void)tabView:(id)fp12 didSelectTabViewItem:(id)fp16;
	- (void)selectExporter:(id)fp12;
	- (id)exportView;
	- (BOOL)_hasPlugins;
	- (void)_resizeExporterToFitView:(id)fp12;
	- (void)_updateImageCount;
	
	@end
	
	@interface ExportMgr : NSObject <ExportImageProtocol>
	{
	    ArchiveDocument *mDocument;
	    NSMutableArray *mExporters;
	    Album *mExportAlbum;
	    NSArray *mSelection;
	    ExportController *mExportController;
	}
	
	+ (id)exportMgr;
	+ (id)exportMgrNoAlloc;
	- (id)init;
	- (void)dealloc;
	- (void)releasePlugins;
	- (void)setExportController:(id)fp12;
	- (id)exportController;
	- (void)setDocument:(id)fp12;
	- (id)document;
	- (void)updateDocumentSelection;
	- (unsigned int)count;
	- (id)recAtIndex:(unsigned int)fp12;
	- (void)scanForExporters;
	- (unsigned int)imageCount;
	- (BOOL)imageIsPortraitAtIndex:(unsigned int)fp12;
	- (id)imagePathAtIndex:(unsigned int)fp12;
	- (struct _NSSize)imageSizeAtIndex:(unsigned int)fp16;
	- (unsigned int)imageFormatAtIndex:(unsigned int)fp12;
	- (id)imageCaptionAtIndex:(unsigned int)fp12;
	- (id)thumbnailPathAtIndex:(unsigned int)fp12;
	- (id)imageDictionaryAtIndex:(unsigned int)fp12;
	- (float)imageAspectRatioAtIndex:(unsigned int)fp12;
	- (id)albumName;
	- (id)albumMusicPath;
	- (unsigned int)albumCount;
	- (unsigned int)albumPositionOfImageAtIndex:(unsigned int)fp12;
	- (id)imageRecAtIndex:(unsigned int)fp12;
	- (id)currentAlbum;
	- (void)enableControls;
	- (void)disableControls;
	- (id)window;
	- (void)clickExport;
	- (void)startExport;
	- (void)cancelExport;
	- (void)cancelExportBeforeBeginning;
	- (id)directoryPath;
	- (void)_copySelection:(id)fp12;
	- (id)temporaryDirectory;
	- (BOOL)doesFileExist:(id)fp12;
	- (BOOL)doesDirectoryExist:(id)fp12;
	- (BOOL)createDir:(id)fp12;
	- (id)uniqueSubPath:(id)fp12 child:(id)fp16;
	- (id)makeUniquePath:(id)fp12;
	- (id)makeUniqueFilePath:(id)fp12 extension:(id)fp16;
	- (id)makeUniqueFileNameWithTime:(id)fp12;
	- (BOOL)makeFSSpec:(id)fp12 spec:(struct FSSpec *)fp16;
	- (id)pathForFSSpec:(id)fp12;
	- (BOOL)getFSRef:(struct FSRef *)fp12 forPath:(id)fp16 isDirectory:(BOOL)fp20;
	- (id)pathForFSRef:(struct FSRef *)fp12;
	- (unsigned long)countFiles:(id)fp12 descend:(BOOL)fp16;
	- (unsigned long)countFilesFromArray:(id)fp12 descend:(BOOL)fp16;
	- (unsigned long long)sizeAtPath:(id)fp12 count:(unsigned long *)fp16 physical:(BOOL)fp20;
	- (BOOL)isAliasFileAtPath:(id)fp12;
	- (id)pathContentOfAliasAtPath:(id)fp12;
	- (id)stringByResolvingAliasesInPath:(id)fp12;
	- (BOOL)ensurePermissions:(unsigned long)fp12 forPath:(id)fp16;
	- (id)validFilename:(id)fp12;
	- (id)getExtensionForImageFormat:(unsigned int)fp12;
	- (unsigned int)getImageFormatForExtension:(id)fp12;
	- (struct OpaqueGrafPtr *)uncompressImage:(id)fp12 size:(struct _NSSize)fp16 pixelFormat:(unsigned int)fp24 rotation:(float)fp36;
	- (void *)createThumbnailer;
	- (void *)retainThumbnailer:(void *)fp12;
	- (void *)autoreleaseThumbnailer:(void *)fp12;
	- (void)releaseThumbnailer:(void *)fp12;
	- (void)setThumbnailer:(void *)fp12 maxBytes:(unsigned int)fp16 maxWidth:(unsigned int)fp20 maxHeight:(unsigned int)fp24;
	- (struct _NSSize)thumbnailerMaxBounds:(void *)fp16;
	- (void)setThumbnailer:(void *)fp12 quality:(int)fp16;
	- (int)thumbnailerQuality:(void *)fp12;
	- (void)setThumbnailer:(void *)fp12 rotation:(float)fp36;
	- (float)thumbnailerRotation:(void *)fp12;
	- (void)setThumbnailer:(void *)fp12 outputFormat:(unsigned int)fp16;
	- (unsigned int)thumbnailerOutputFormat:(void *)fp12;
	- (void)setThumbnailer:(void *)fp12 outputExtension:(id)fp16;
	- (id)thumbnailerOutputExtension:(void *)fp12;
	- (BOOL)thumbnailer:(void *)fp12 createThumbnail:(id)fp16 dest:(id)fp20;
	- (struct _NSSize)lastImageSize:(void *)fp16;
	- (struct _NSSize)lastThumbnailSize:(void *)fp16;
	
	@end
	
	@interface ExportMgrRec : NSObject
	{
	    NSString *mPath;
	    NSBundle *mBundle;
	    id mPlugin;
	    struct _NSSize mViewSize;
	}
	
	- (void)dealloc;
	- (BOOL)isEqual:(id)fp12;
	- (id)description;
	- (id)initWithPath:(id)fp12;
	- (id)path;
	- (id)bundle;
	- (id)bundleInfo;
	- (BOOL)isValidExportPlugin;
	- (BOOL)loadPlugin;
	- (id)exportPlugin;
	- (void)unloadPlugin;
	- (id)view;
	- (struct _NSSize)viewSize;
	- (void)setPath:(id)fp12;
	- (void)setBundle:(id)fp12;
	
	@end

