The Shape of Everything
A website mostly about Mac stuff, written by Gus Mueller
» Acorn
» Twitter
» Maybe Pizza?
» Code
» Archive
October 16, 2015

Acorn 5.1.1 is mostly about bug fixes (out now for direct, waiting for review for Apple's App Store), but I did manage to add a couple of new Automator actions to it- Scale and Export to Folder.

Dev talk: an Automator extension is a little Cocoa bundle that gets run in another process, so you need to find some way to communicate from that bundle to your application. For Acorn, I use Distributed Objects. And for years it worked great, until the App Store Sandbox was introduced. (Boo, hiss!)

Since the Sandboxed version of Acorn didn't have permission to open files or save files that it hadn't previously encountered, batch processing things in Automator became pretty impossible. Apple had "solved" this for most developers who script their apps using AppleScript. When you pass an AppleScript file reference to your app, some magic happens in the background and holes are punched in the Sandbox, which allows the app to open and save to locations that it otherwise wouldn't be allowed to.

But adding AppleScript support is a pain in the ass, so I mostly avoided it and encouraged folks to use the direct version of Acorn if they wanted to do batch processing of things.

But recently when working on the new export action, I wondered if AppleScript was sending around NSURL Bookmark data for the file references, and maybe that was how it was able to get through the sandbox restrictions. So I tried that out, but with no luck. You can't make a bookmark to a file that doesn't exist- which is what I'd need for exporting images. Magic Apple Events were still needed if I wanted write to new files from the sandbox.

But then I came up with a stupid idea. What if I made a new Apple Event, similar to the open document event, which instead of trying to open a file that doesn't exist… just did nothing? We'll call it "sandopen" and all it does it receives a file reference to a (non-existent) file that I'm about to tell Acorn to write to. In essence, it's saying "Here's a file reference that I want you to use your magic sandbox hole punching abilities on for me. Just ignore the fact that I'm not doing anything to it in this event, but rather the next one".

So the automator action sends that event to Acorn first and then tells it over Distributed Objects to save to the location.

And it worked!

So there's a handy little developer tip for you. I still hate the Mac sandbox.