2

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*?

iluvcapra
  • 9,436
  • 2
  • 30
  • 32

2 Answers2

1

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.

Chris N
  • 905
  • 5
  • 10
  • I'll try this, but I suspect my receiving application won't do it -- it's a very proprietary app. (I'm not naming names, but it's Avid Pro Tools.) – iluvcapra Mar 31 '13 at 22:30
  • 2
    I suspect you can actually use type coercion in your own code to create the alias record from the file URL without deprecated API and then put that on the event you send. That is, store a `typeFileURL` into a record and then retrieve a `typeAlias`. Then store that `typeAlias`. – Ken Thomases Mar 31 '13 at 22:49
  • 2
    Honestly, Avid would have had to go out of their way to make their side not work. However, if they did, then Ken’s suggestion of coercing would work, except that I’d use `-[NSAppleEventDescriptor coerceToDescriptorType:]` (or, if you prefer, `AECoerceDesc`). – Chris N Apr 01 '13 at 06:45
0

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];
}
AriX
  • 1,647
  • 2
  • 18
  • 24
  • I tried this first when I started having this problem -- your solution works in general but not for the particular app I was using. It only wants to see an alias, it can't handle `typeBookmarkData`. – iluvcapra May 13 '14 at 00:36
  • Got it. My answer to that would be "coerce it" but it sounds like that is what you ended up doing, but with a file URL instead. – AriX May 14 '14 at 07:10
  • I think I tried that and it didn't work for some reason. It seems like if you can coerce a bookmark to a file path, that defeats the purpose of having bookmarks. – iluvcapra May 14 '14 at 18:11
  • Not quite sure what you mean! Bookmarks are just a more modern version of aliases; both can be coerced to file paths. But they're not the same thing (i.e. if you store a bookmark to a file, and then move it somewhere else, it can still be found, whereas the file's path changes) – AriX May 15 '14 at 01:54