Aperture Plugin: Implementing A Table Of Images

cocoasmall
At this point in the project I decided two things: that I was going to release the plugin as 1.0 in a month, and that I needed to change the interface. I had already switched from a vertical arrangement with the prefix on top, to a horizontal arrangement with the prefix on the left. The trigger for this next change was the unsatisfactory display of the example random filename and the need to distinguish between what happens to the random naming when the freeze feature is used and is not.

The final version I decided to go with features a table that shows a thumbnail, plus the image version name, the image caption, and the new random name. This is the clearest way to show what is going to happen: show it happening.
rw1.0mm
By using the propertiesWithoutThumbnailForImageAtIndex: and thumbnailForImageAtIndex: methods I can get the data I need from Aperture for each table entry. So my plan was to bind the table to an array controller and bind the array controller to an array in the Random_Wok object that contained all the thumbnails and text. Updating the thumbnails and text would cause changes to propagate through the controller to the view as needed.

So I added an array controller to the nib and called it ImageTable:
rwok305
I then bound it to the model like this:
rwok306
and set up like this:
rwok307
The model key is imageTableData and I use the keys thumb and text to access the data for the columns. So to support the needs of the array controller I implement an array called imageTableData as an ivar in Random_Wok and fill it with dictionaries with keys thumb and text, corresponding to NSImage and NSString objects I want to display.

I set up the table view like this:
rwok300
Notice that I actually used a custom class for this. More on that later. The first (image) column is set up like this:
rwok301
To display the image, I drag in an image cell. The properties of the image cell is accessed via the small triangle top right:
rwok302
The inspector shows it as an NSImageCell, set up this way:
rwok303
Now onto the bindings. The first column is bound to the array controller and uses the thumb key to get data from the model:
rwok304
The second column is set up this way:
rwok308
And bound to the text key through the array controller like this:
rwok309

As I discovered while attempting to bind each table column to a separate array, setting up table column bindings also automatically sets up the the table bindings. This makes it impossible to bind separate columns to separate array objects: they have to all go to one object and then use the key path to get data from separate places. This pretty much means that you need an array of dictionaries to drive a table.

To provide data for the model, I loaded all the thumbnails and text into the array during the plugin initialization. Through the bindings I was able to change the dictionary contents and have the table update automatically. This all worked fine for a small selection of images.

However if I selected 500 images, the array would take a long time to fill. Worse, this was happening before anything was displayed (since the array controller was set to prepare content), making it look like the plugin has frozen. And changes to the text caused by changing the parameters for the random file names were also very slow because they too would be performed 500 times on all the items in the array.

So another approach was needed.

The other parts of this series can be found via the Cocoa page.
The Bagelturf site welcomes Donations of any size