startup junkie

0 notes &

Deduplicating Running Instances (or how to detect if your Cocoa application is already running)

Have you ever encountered a coding problem that you would really like a solution to but you just can’t seem to find an elegant fix? So instead, you just put it on the back burner, hoping that one day, you’ll be smarter, and a beautiful solution will descend upon your project and fix everything?

Yeah. Frequently.

Well, today, the stars aligned and I suddenly realized how to resolve one of these delayed problems! And the answer was so simple that I had to share it…

The Problem

Let’s say you want to prevent the user from running more than one copy of your application at a given time. This is a likely scenario if your app depends on shared resources or takes some action during execution that would break if repeated. Fortunately, it turns out that there is a very easy way to detect this scenario during application startup.

The Solution

Using the NSRunningApplication facility in Snow Leopard, we can detect this with a single line of code. And, by loading all the information we need from the application’s bundle, this code will work as-is in any application:

- (void)deduplicateRunningInstances {
if ([[NSRunningApplication runningApplicationsWithBundleIdentifier:[[NSBundle mainBundle] bundleIdentifier]] count] > 1) {
[[NSAlert alertWithMessageText:[NSString stringWithFormat:@"Another copy of %@ is already running.", [[NSBundle mainBundle] objectForInfoDictionaryKey:(NSString *)kCFBundleNameKey]] 
defaultButton:nil alternateButton:nil otherButton:nil informativeTextWithFormat:@"This copy will now quit."] runModal];

[NSApp terminate:nil];
}
}

Once detected, it is equally simple to display an alert message to the user and terminate.

Call this method from -applicationDidFinishLaunching: and everything will be taken care of.