Published by Simon Schoeters

Updating bundles with Sparkle

Did you ever use the Sparkle framework in your Cocoa applications? It's a great framewok that makes it easy for end-users to update your Mac OS X applications when a new version is released. We use it for Lustro, our first Cocoa application. It's fairly easy to install and well documented. The problem is I needed it for a Cocoa bundle (also called a non-app bundle): a preference pane we want to install in the Mac OS X System Preferences.

The Sparkle documentation has some bundle installation instructions but my Cocoa level is not good enough to understand the different steps. Let's see how we can activate Sparkle for our own bundle, step by step (I'm using version 1.5 b6 here).

Basic setup

Start with the first step from the Basic Setup guide. This step is the same for normal applications or non-app bundles.

Build the interface

  • Open up your NIB file in Interface Builder.
  • Go to ‘File → Read Class Files...’ and choose all the files inside Sparkle.framework/Headers.
  • Drag a generic Object (a blue cube) from the Library to your document.
  • Select this object in your document window, and under the Information tab of the inspector, set the class of the object to SUUpdater.
  • If you'd like, make a ‘Check for Updates...’ menu item in the application menu. Set its target to the SUUpdater instance and its action to checkForUpdates:.

Bundle specific setup

Now import the Sparkle header in your own header class with:

#import <Sparkle.h>

We need to instantiate the SUUpdater in our code, something that you don't need to do for a full blown application. I added the following to my awakeFromNib method (that method will be loaded when the user opens your preference pane).

- (void)awakeFromNib
  SUUpdater *updater =
  [SUUpdater updaterForBundle:[NSBundle bundleForClass:[self class]]];
  [updater setAutomaticallyChecksForUpdates:YES];
  [updater resetUpdateCycle];

Custom bundle identifier

This will work but is incorrect. Sparkle will now write it's user defaults in the which is a wrong practice. Sparkle will get confused as soon as 2 or more bundles use this method (the will use the same variables). You'll need to point Sparkle to identifier specific for you bundle. Luckily we can tell Sparkle to use our bundle:

[NSBundle bundleWithIdentifier:@""]

Replace the ‘com.example.yourbundle’ with your own bundle identifier.

User defaults

Start your bundle and click the update button. Close the System Preferences and check the user defaults to see if it works. There is a nice command in Mac OS X called ‘defaults’ that can read these user defaults for you (be sure to close the application first as it will only write the new settings to disk when the application closes). Open Terminal and type:

defaults read com.example.yourbundle

Look for ‘SU-’ prefixed parameters. Do you see them? That should be all for today. You can have a look in our code to see how the end result looks like.