• Open Menu Close Menu
  • Apple
  • Shopping Bag
  • Apple
  • Mac
  • iPad
  • iPhone
  • Watch
  • TV
  • Music
  • Support
  • Search apple.com
  • Shopping Bag

Lists

Open Menu Close Menu
  • Terms and Conditions
  • Lists hosted on this site
  • Email the Postmaster
  • Tips for posting to public mailing lists
Re: path name from Apple Event
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: path name from Apple Event


  • Subject: Re: path name from Apple Event
  • From: Bill Monk <email@hidden>
  • Date: Tue, 16 Aug 2005 12:33:08 -0500


they always work as long as one is using the proper - cat-specific - way of accessing them.

This code seems to work:

if ( we run on Tiger )
{
// Panther would return nil for coerceToDescriptorType: typeFileURL
NSAppleEventDescriptor *urlDesc = [ aliasED coerceToDescriptorType: typeFileURL];
}
else // we run on Panther
{
// Tiger would return paramErr for FSResolveAliasWithMountFlags
FSResolveAliasWithMountFlags()
};



Well, the reason why ResolveAlias is failing here is that you're handing it what used to be called a "fake handle" (there was a Tech Note on the subject back in the deeps of time). Unfortunately when you dig very deep into Apple Events, you enter the Carbon world, and its rules apply. A Handle is not just a pointer to a pointer cobbled together with a bit of C...


This code:

void *bytes = malloc( len );
[ data getBytes: bytes ];
AliasPtr aliasPtr = bytes ;
AliasHandle aliasHandle = &aliasPtr ;

won't work. That is the very definition of a fake handle, and if it works on Panther, it's an accident and not to be depended upon. Tiger is evidently more strict, hence the paramErr. (FWIW, Carbon paramErrs always mean exactly that - in my experience, they are *always* my fault.)



A second problem in the code is this:

NSAppleEventDescriptor *dirctObj = [ event descriptorForKeyword: keyDirectObject ];
NSAppleEventDescriptor *aliasED = [ dirctObj descriptorAtIndex: 1 ];
NSData *data = [ aliasED data ];

This assumes the direct object will be a 'list' descriptor containing 'alis' descriptors. But it doesn't have to be that way. For a single file, the direct object may just be an 'alis'; there doesn't have to be a list at all. If this happens, and it will, the above code tries to get the data from the wrong place.


I haven't verified it, but I'll bet this is why coerceToDescriptorType: isn't working for you under Panther. Either Panther (or more likely, the version of Xcode running there, since your app gets these events from Xcode) is passing a single alias as the direct object, not as the list of aliases your code expects. If so, descriptorAtIndex: then hands you a typeNull descriptor when you ask for item 1 of the list. typeNull obviously can't coerce to typeFileURL, so it appears not to work on Panther.

In Xcode 2.x, (and who knows why, but there doesn't have to be a reason why, both ways are valid) single aliases are evidently passed as a one-item list of aliases within the direct object, and not *as* the direct object. In this case, your NSData code would work, but then the fake handle would cause Tiger's more strict ResolveAlias() to fail, and so it seems ResolveAlias() isn't working on Tiger.

I'm guessing the problems are not actually OS-related, but simply due to different Xcode versions and how they send 'odoc' events, along with a Carbon-era gotcha and a fairly obscure Apple Event detail.


Here's some code. It's going to wrap horribly. But it should help:



- (void)handleODOCEvent:(NSAppleEventDescriptor *)event withReplyEvent:(NSAppleEventDescriptor *)replyEvent;
{
OSErr myErr = noErr;


NSAppleEventDescriptor *dirObj = [event descriptorForKeyword:keyDirectObject];
DescType dirObjType = [dirObj descriptorType];


    NSData *data;
    FSRef   fsRef;
    Boolean wasChanged;
    AliasHandle aliasHandle;

    if ( dirObjType == 'alis' ) {    // open one file

data = [dirObj data];
aliasHandle = (AliasHandle)NewHandle( [data length] ); // get a real Handle
if ( NULL != aliasHandle ) {


[data getBytes: *aliasHandle];
myErr = FSResolveAliasWithMountFlags(NULL, aliasHandle, &fsRef, &wasChanged, kResolveAliasFileNoUI);
DisposeHandle( (Handle)aliasHandle );


CFURLRef resolvedUrl = CFURLCreateFromFSRef(NULL, &fsRef);
NSString *resolvedPath = (NSString*) CFURLCopyFileSystemPath( resolvedUrl, kCFURLPOSIXPathStyle);
CFRelease(resolvedUrl);
NSLog( @"Path: %@", resolvedPath );
// do whatever with resolvedPath
}
} else if ( dirObjType == 'list' ) { // open many files


aliasHandle = (AliasHandle)NewHandle( 0L ); // get a real Handle; we'll resize as needed.
if ( NULL != aliasHandle ) {


            int numItems = [dirObj numberOfItems];
            int i;
            for ( i = 1; i <= numItems; i++ ) {

NSAppleEventDescriptor *thisAlias = [dirObj descriptorAtIndex:i];
data = [thisAlias data];


                SetHandleSize( (Handle)aliasHandle, [data length] );
                myErr = MemError();
                if ( noErr == myErr ) {

[data getBytes: *aliasHandle];
myErr = FSResolveAliasWithMountFlags(NULL, aliasHandle, &fsRef, &wasChanged, kResolveAliasFileNoUI);
if ( noErr == myErr ) {


CFURLRef resolvedUrl = CFURLCreateFromFSRef (NULL, &fsRef);
NSString *resolvedPath = (NSString*) CFURLCopyFileSystemPath(resolvedUrl, kCFURLPOSIXPathStyle);
CFRelease(resolvedUrl);
NSLog( @"Path: %@", resolvedPath );
// do whatever with resolvedPath
}
}
}
DisposeHandle( (Handle)aliasHandle );
}
}


// Would need more logic to decide whether to fill in an error reply;
// for example, if one alias out of a long list failed to resolve, we
// probably would not complain.
if ( (noErr != myErr) && ([replyEvent descriptorType] != typeNull) ) {


NSAppleEventDescriptor *errNumDesc = [NSAppleEventDescriptor descriptorWithInt32:myErr];
[replyEvent setParamDescriptor:errNumDesc forKeyword:keyErrorNumber];


NSAppleEventDescriptor *errStrDesc = [NSAppleEventDescriptor descriptorWithString:@"Complain."];
[replyEvent setParamDescriptor:errStrDesc forKeyword:keyErrorString];
}
}


_______________________________________________
Do not post admin requests to the list. They will be ignored.
Cocoa-dev mailing list      (email@hidden)
Help/Unsubscribe/Update your Subscription:
This email sent to email@hidden


  • Prev by Date: Re: CoreData "Could Not Merge Changes"
  • Next by Date: +[NSColor colorWithPatternImage:] - set pattern origin?
  • Previous by thread: Re: path name from Apple Event
  • Next by thread: Sync services notification
  • Index(es):
    • Date
    • Thread