views:

186

answers:

2

My Mac OS X application receives a file over the network (in this case, text/x-vcard). In my code, how can I open the related application (typically the Address Book) without hard-coding paths or application name so that it processes the file ?

+2  A: 

You'll be able to do this by linking in the ApplicationServices framework, which has a really handy "LSCopyApplicationForMIMEType" function. It works like this:

CFURLRef appURL = nil;
OSStatus err = LSCopyApplicationForMIMEType(CFSTR("text/x-vcard"), kLSRolesAll, &appURL);

if (err != kLSApplicationNotFoundErr) {
  NSLog(@"URL: %@", (NSURL *)appURL);
}

CFRelease(appURL);

I'll explain what the parameters mean. The first parameter is a CFStringRef of the MIME type you're looking up. The second parameter indicates what kind of application you're looking for, ie an app that can edit this file, or an app that can view this file, etc. kLSRolesAll means you don't care. The final parameter is a pointer to the CFURLRef where the function will stick the app's URL (if it can find one).

On my machine, this prints out:

2009-08-01 12:38:58.159 EmptyFoundation[33121:a0f] URL: file://localhost/Applications/Address%20Book.app/

One of the cool things about CFURLRefs is that they're toll-free bridged to NSURL. This means you can take a CFURLRef and cast it to an NSURL, and vice versa. Once you've got your NSURL of the app, it's pretty trivial to use something like NSWorkspace's -launchApplicationAtURL:options:configuration:error: method to open the application.

If you want to open a specific file in that application (like the file from which you got the MIME type), you could use something like -[NSWorkspace openFile:withApplication:].

If you can't get the MIME type (despite what you say in your question), there are a bunch of similar LaunchServices functions. You can read all about them here.

Dave DeLong
Thanks ! That is exactly what I need.
Mike Camilo
A: 

Rather than even bothering to try to find the application you can use LSOpenItemsWithRole.

//Opens items specified as an array of values of type FSRef with a specified role.

OSStatus LSOpenItemsWithRole (
    const FSRef *inItems,
    CFIndex inItemCount,
    LSRolesMask inRole,
    const AEKeyDesc *inAEParam,
    const LSApplicationParameters *inAppParams,
    ProcessSerialNumber *outPSNs,
    CFIndex inMaxPSNCount
);
Seth