Extending PhotoLinker with Plugins
Starting with version 2.5 PhotoLinker supports photo export plugins. A photo export plugin is given access to the readonly copies of photos and metadata fields.
The best way to get started writing a plugin is probably to download the SDK and sample code.
Included in the SDK are the header files, and two sample projects: the metadata exporter and the simple file exporter. Both of these sample plugins are the same that ship with the current version of PhotoLinker. The slide show in PhotoLinker is also built from the same APIs, but it also has access to the track files which aren't yet publicly available.
Writing a photo export plugin
A photo export plugin is given access to the readonly copies of photos and metadata fields.
In the root folder there currently the folders PhotoExportSDK PhotoExportSDK/Headers PhotoExportSDK/MetadataExporters PhotoExportSDK/SimpleFileExporter
The Headers folder contains the only information that a plugin needs to work.
The plugin and the host application (PhotoLinker) have a well defined way of communicating with each other.
PhotoLinker -> plugin. PhotoLinker expects the plugin's principal class to respond to certain methods and therefore the plugin's principal class must conform to the GLPhotoExportPlugin protocol. The order in which PhotoLinker calls the plugin's methods are detailed below.
Plugin -> PhotoLinker. The plugin's primary interface to the PhotoLinker is through an instance of GLPhotoExportManager. The export manager instance has access to read only copies of photos, metadata fields, and can handle some basic image resizing.
Creating a new plugin
To create a new plugin in Xcode,
- File > New Project… and selected "Bundle" from the "Mac OS X -> Framework & Library" section. Set the framework to Cocoa. Enable Automatic Referencing Counting. Save this in the PhotoExportSDK folder.
- Get Info on the bundle target and change the following build settings for All Configurations:
- Base SDK: 10.7
- Deployment Target: 10.6
- Wrapper Extension: glplugin
- Skip Install: Yes
- Force Package Info Generation: Yes
- Drag in the header files folder. Just refer to them with their relative path in your source code, e.g., #import "../Headers/GLPhoto.h".
- Create a new subclass of NSObject, such as ExportTest and indicate that it conforms to the GLPhotoExportPlugin protocol. You do this by writing
in the interface, see the example.
- In the Info.plist (or get info on the target and look under the properties tab), be indicate the name of the principal class, the class that conforms to the plugin protocol, e.g., GLSimpleFileExporter.
- Double-clicking the final built product will cause PhotoLinker to make a copy of the plugin and then load it.
Implementing a plugin
The basic idea is that your principal class gets loaded, but not initialized when the app starts up. The application calls the class methods +uuid and +name just to add it to the menu, after checking that it conforms to the protocol.
When the user selects the plugin from the menu, the application initializes your plugin with, - (id)initWithAPIManager: (id) apiManager; This apiManager object you need to query to get a copy of the "GLPhotoExportManager" object. The export manager is your friend and the plugin's primary interface to PhotoLinker. Hold on to it.
The export manager is the only "active" way that the plugin can interact with PhotoLinker. If you look at the "GLPhotoExportManager.h" header file, you can see that this is how you get copies of photos, metadata fields, and (eventually) tracks. Also, the export manager has the very, very useful command -exportPhoto:toPath:withOptions which, as the name implies, will take a GLPhoto object and write an actual image file to the destination path for you. The export manager also has on method to begin the export process and a method to cancel.
Basically just read the notes in the GLPhotoExportPlugin.h header file, that gives the basic order of events. So,
- -initWithAPIManager is called.
- The "Save/Path Methods" methods are called to find out if the plugin just needs a basic type of save prompt, or needs its own custom sheet. 3a. If you just need a save prompt, -settingsView will be called and if it's not nil, will be added to the save prompt. 3b. If you need your own custom sheet, then -settingView will be called and placed on a custom sheet. Just change -wantsDestinationPathPrompt to NO in the simple exporter to see the difference.
- -shouldPrepareForExportToPath: will then be called. If everything looks good (internet connection okay, path valid, etc.), then tell the export manager -exportManagerShouldBeginExport.
- -performExport is then called. This is where you do the hard work.