Creating an AppleEvent descriptor for an alias in OS X 10.8

550 views Asked by At

I have the following code in a project

NSAppleEventDescriptor *JHCreateAliasDescriptorForURL(NSURL *aURL) {
    NSAppleEventDescriptor *retObj = nil;
    FSRef fsReference;

    if (CFURLGetFSRef((__bridge CFURLRef)aURL, &fsReference)) {
        AliasHandle aliasHandle = NULL;
        OSStatus err = FSNewAliasMinimal(&fsReference, &aliasHandle);
        if (err == noErr && aliasHandle != NULL) {

            HLock((Handle)aliasHandle);
            retObj = [NSAppleEventDescriptor descriptorWithDescriptorType:typeAlias
                            data:[NSData dataWithBytes:*aliasHandle
                                                length:GetHandleSize((Handle)aliasHandle)]];
            HUnlock((Handle)aliasHandle);
            DisposeHandle((Handle)aliasHandle);
        }
    }

    return retObj;
}

It creates an alias descriptor that passes a file to a program that is not applescriptable but responds to this one AppleEvent.

When I compile this under 10.8, I get warnings because all the Carbon FSNewAlias* functions are deprecated and we're supposed to be using opaque bookmark NSData objects out of the NSURL API. However, I've had no luck turning this data into alias AppleEvent descriptors.

How can I make a typeAlias descriptor in 10.8 without FSNewAlias*?

2

There are 2 answers

3
Chris N On BEST ANSWER

You basically can’t. (The modern replacement for Alias is CFURLBookmark. There’s a routine to create a Bookmark from Alias data, but not the other way around.) What you can do, however, is create a different kind of file descriptor which is coercible to an alias -- the most straightforward is typeFileURL, where the contents are simply the bytes of the URL. This is admittedly dependent on the target application being written properly, but it should work.

4
AriX On

In case anyone else is looking for a more direct solution, something like this works well to create a Apple Event descriptor from bookmark data:

+ (NSAppleEventDescriptor *)descriptorWithBookmarkDataForFileURL:(NSURL *)fileURL {
    NSData *targetBookmarkData = [fileURL bookmarkDataWithOptions:0 includingResourceValuesForKeys:nil relativeToURL:nil error:nil];
    return [NSAppleEventDescriptor descriptorWithDescriptorType:typeBookmarkData data:targetBookmarkData];
}