parameter passing from cocoa to AS
parameter passing from cocoa to AS
- Subject: parameter passing from cocoa to AS
- From: "Philip Lukidis" <email@hidden>
- Date: Thu, 13 Jul 2006 14:30:49 -0400
- Thread-topic: parameter passing from cocoa to AS
Hello. I need to pass an object to one of my prototype iTunes management scripts (Applescript). It is a simple script which plays the track passed by the caller. So far I can send an integer/string argument to my script, but passing an object seems to be more difficult. I'll explain the details below.
This is the play event extracted from the iTunes dictionary by HAS' freeware tool HTMLDictionary (http://freespace.virgin.net/hamish.sanderson/index.html). We can see that it requires an object in order that a specified track be played, otherwise the current track would be played
Event: play [hookPlay] -- play the current track or the specified track or file.
<obj > (optional) -- item to play
once [POne] <bool> (optional) -- If true, play this track once and then stop.
Result: <null>
This is my script which returns track objects from the main iTunes library- the copy command seems to return the track objects in a list to the caller (tested with many track attributes as well, like artist, album, etc):
tell application "iTunes"
activate
tell every track of library playlist 1
copy container to track_name
end tell
end tell
I invoke the script above from my cocoa program, and I receive a list descriptor with all the track objects. I then parse the list, and extract the objects as follows (well for now I only extract one object):
if((cObjectSpecifier==[pCurrentDesc descriptorType]) && (g_TrackToPlay==nil))
{
//g_TrackToPlay = [NSData dataWithData:pCurrentData];
//pCurrentData = [pCurrentDesc data];
theLength = AEGetDescDataSize(pCurrentAEDesc); // note this is 152 bytes
theData = calloc(1,theLength);
if(theData)
{
err = AEGetDescData(pCurrentAEDesc, theData, theLength);
if(err == noErr)
{
g_TrackToPlay = [NSData dataWithBytes:theData length:theLength];
}
}
}
Now I want to pass this object to my play script, which is as follows:
on play_target_track(track_to_play)
tell application "iTunes"
play track_to_play
end tell
end play_target_track
I call the script above as follows (note that this code works when passing an integer to the script, but for the parameter I create the descriptor differently ([NSAppleEventDescriptor descriptorWithInt32:trackNum]):
NSURL *url = [NSURL fileURLWithPath:@"/testplay.scpt"];
NSDictionary *ASInitErrors=[[NSDictionary alloc] init],*compError=[[NSDictionary alloc] init],
*sendError=[[NSDictionary alloc] init];
if(url)
{
// load the script from a resource
NSAppleScript *appleScript = [[NSAppleScript alloc] initWithContentsOfURL:url error:&ASInitErrors];
if(appleScript && (g_TrackToPlay!=nil))
{
[appleScript compileAndReturnError:&compError];
NSAppleEventDescriptor *firstParameter = [NSAppleEventDescriptor descriptorWithDescriptorType:cObjectSpecifier bytes:[g_TrackToPlay bytes] length:[g_TrackToPlay length]];
NSAppleEventDescriptor *parameters = [NSAppleEventDescriptor listDescriptor];
[parameters insertDescriptor:firstParameter atIndex:1];
ProcessSerialNumber psn = { 0, kCurrentProcess };
NSAppleEventDescriptor *target = [NSAppleEventDescriptor descriptorWithDescriptorType:typeProcessSerialNumber bytes:&psn length:sizeof(ProcessSerialNumber)];
NSAppleEventDescriptor *handler = [NSAppleEventDescriptor descriptorWithString:[@"play_target_track" lowercaseString]];
NSAppleEventDescriptor *event = [NSAppleEventDescriptor appleEventWithEventClass:kASAppleScriptSuite eventID:kASSubroutineEvent targetDescriptor:target returnID:kAutoGenerateReturnID transactionID:kAnyTransactionID];
[event setParamDescriptor:handler forKeyword:keyASSubroutineName];
[event setParamDescriptor:parameters forKeyword:keyDirectObject];
if(![appleScript executeAppleEvent:event error:&sendError]);
{
ParseDictionaryForErrors:sendError;
}
[appleScript release];
}
else
{
// failed to create applescript object, or non existent track to play
}
}
my dictionary parsing routine is here:
-(void) ParseDictionaryForErrors:(NSDictionary*)pDictionaryToParse
{
NSArray *keys;
NSArray *values;
NSString *pStr;
int keyCount, i, valueCount;
Class theClass;
keys = [pDictionaryToParse allKeys];
keyCount = [keys count];
int currKey=0;
int num=0;
NSRange range;
for (i = 0; i < keyCount; i++)
{
id key = [keys objectAtIndex:i];
if ([key isKindOfClass:[NSNumber class]])
{
currKey = [(NSNumber *)key intValue];
num = [(NSNumber *)key intValue];
NSLog(@"ParseDictionaryForErrors(): (key) count:%u, num:%d",
i,
num);
}
else if([key isKindOfClass:[NSString class]])
{
pStr = (NSString*)key;
NSLog(@"ParseDictionaryForErrors(): (key): count:%u, str:%@",
i,
pStr);
}
else
{
theClass = [key class];
}
}
values = [pDictionaryToParse allValues];
valueCount = [values count];
for (i = 0; i < keyCount; i++)
{
id val = [values objectAtIndex:i];
theClass = [val class];
if ([val isKindOfClass:[NSNumber class]])
{
num = [(NSNumber *)val intValue];
NSLog(@"ParseDictionaryForErrors(): (value) count:%u, num:%d",
i,
num);
}
else if([val isKindOfClass:[NSString class]])
{
pStr = (NSString*)val;
NSLog(@"ParseDictionaryForErrors(): (value) count:%u, str:%@",
i,
pStr);
}
else if([val isKindOfClass:[NSValue class]])
{
// This is private NSConcreteValue subclass...according to the archives
range = [ (NSValue*)val rangeValue];
NSLog(@"ParseDictionaryForErrors(): (value) count:%u, range location:%d, length:%d",
i,
range.location,
range.length);
}
}
}
It's output is:
dictionary keys:
ParseDictionaryForErrors(): (key): count:0, str:NSAppleScriptErrorNumber
ParseDictionaryForErrors(): (key): count:1, str:NSAppleScriptErrorMessage
ParseDictionaryForErrors(): (key): count:2, str:NSAppleScriptErrorRange
ParseDictionaryForErrors(): (key): count:3, str:NSAppleScriptErrorBriefMessage
dictionary values:
ParseDictionaryForErrors(): (value) count:0, num:-1728
ParseDictionaryForErrors(): (value) count:1, str:Can't get «class cLiP» id 51 of «class cSrc» id 37.
ParseDictionaryForErrors(): (value) count:2, range location:0, length:0
ParseDictionaryForErrors(): (value) count:3, str:Can't get «class cLiP» id 51 of «class cSrc» id 37.
Can anyone tell me what I'm doing wrong here? It looks like the script does not understand my parameter, or I have retrieved it/passed it incorrectly. Any pointers?
thanks,
Philip Lukidis
_______________________________________________
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