[NSBundle bundleWithIdentifier:]

I’m having an issue with calling a specific NSBundle method, and I’m stumped at this point. I’m sure it’s something obvious that I’ve missed. A bit of code to demonstrate what I’m scratching my head over:

set omgLOL to call method "bundleWithIdentifier:" of class "NSBundle" with parameter "com.apple.iTunes"

This doesn’t seem to return an application path, when it appears as though it should. (iTunes used here for discussion’s sake.)

What the heck am I missing?

From ADC Documentation:

I had once wanted to look into this, but I never got around to it. Unfortunately, it seems like this won’t do what you want it to do.

If you’re just looking for the path to an application, you could use something like…

tell application "Finder" to set thePath to POSIX path of ((application file id "hook") as string)

The “hook” part is where you identify the unique app ID (file creator) for whatever app you’re trying locate (you’d think iTunes would be “itns” or something a bit more logical, but apple’s power is exceeded only by it’s mystery :D).

If that’s not what you’re trying to do, let us know.

j

Yeah, I don’t like relying on the Finder, so I’m trying to use a Cocoa method to replace the Finder one-liner I have now.

There’s /gotta/ be a way to pull this off. Has to be a method or combination that will accomplish the task!

This is what I use. Make two methods in a class called “methods” like so:

[code]- (NSString *)getAppPath:(NSString *)creatorCode {
NSURL *thisURL;
OSStatus err = LSGetApplicationForInfo(kLSUnknownType, [self osType:creatorCode], nil, kLSRolesAll, (FSRef *)nil, (CFURLRef *)&thisURL);
if (err == noErr) {
return [thisURL path];
} else {
return @“”;
}
}

  • (OSType)osType:(NSString *)str {
    NSString *theStr = [str stringByPaddingToLength:4 withString:@" " startingAtIndex:0];
    const char *cStr=[theStr cString];
    char castStr[4];
    int i;
    for (i=0; i < 4; i++)
    castStr[i]=cStr[i];
    return *(OSType *)castStr;
    }[/code]
    Then call it from your script:
set app_path to (call method "getAppPath:" from class "methods" with parameter "hook")
-->"/Applications/iTunes.app"
set app_path to (app_path as POSIX file) as Unicode text
-->"Macintosh HD:Applications:iTunes.app"

Jon

Jon,

Can that use bundle identifiers or is it limited to old-style creator codes?

No, that method is limited to creator codes but if you want to use a bundle ID, try this method added to a “methods” class:

- (NSString *)getAppPathFromBundleID:(NSString *)bundleID { NSURL *thisURL; OSStatus err = LSFindApplicationForInfo(kLSUnknownCreator, (CFStringRef)bundleID, nil, (FSRef *)nil, (CFURLRef *)&thisURL); if (err == noErr) { return [thisURL path]; } else { return @""; } }
called like so:

set app_path to (call method "getAppPathFromBundleID:" from class "methods" with parameter "com.apple.iTunes")
-->"/Applications/iTunes.app"
set app_path to (app_path as POSIX file) as Unicode text
-->"Macintosh HD:Applications:iTunes.app"

Jon

PS This uses the Launch Services database and, IIRC, this requires that the app must have been launched on the target machine before LS will register it and return the path. If the application is resident but has never been launched, I believe no path will be returned.

Absolutely great, Jon. A thousand thanks. Where did you find this method? (Or did you write it yourself?)

I had to change it from an instance method to a class method, but it’s working perfectly.

I “evolved” them from information I’ve gleaned searching the Xcode documentation and then searching the Cocoa message boards and mailing lists (http://www.cocoabuilder.com/, http://www.cocoadev.com/, etc.) to further illuminate the documentation. I usually find a method and then look for sample code employing the method, then adapt it for my needs.

Jon