Checking running applications the right way

OmniFocus 2 is now in public beta, and I’ve been shifting my scripts over to use its new and improved AppleScript library. Of course, since I ported all my scripts to Cocoa recently, it’s more like I’m digging into the guts of Objective-C, updating some bundled dictionaries, and the like.

All of my OmniFocus export scripts need to check if OmniFocus is running before embarking on data export. Because I’m pulling data out through the app, rather than accessing the database on file, the app needs to be open for these scripts to run. I’ve been using code that looks like the following to do this:

1
2
3
4
5
+(BOOL)isRunning {
  NSString *of2ID = @"com.omnigroup.OmniFocus2";
  OmniFocusApplication *of = [SBApplication applicationWithBundleIdentifier:of2ID];
  return ([of isRunning])
}

However it looks like +[SBApplication applicationWithBundleIdentifier:] will automatically start up the app anyway, which ruins the whole effect.

The correct way to do this in Cocoa is to use NSWorkspace, and my background data extraction apps now use something like this:

1
2
3
4
5
6
7
8
9
+(BOOL) isRunning {
  NSString *of2ID = @"com.omnigroup.OmniFocus2";
  NSArray *apps = [[NSWorkspace sharedWorkspace] runningApplications];
  for (NSRunningApplication *app in apps) {
      if ([app.bundleIdentifier isEqualToString:of2ID])
          return true;
  }
  return false;
}