Getting AppleScript return value in Obj-C

I use some AppleScript in my Obj-C cocoa project to control the QuickTime player (play, pause, stop, push back and forth, etc.) with great success, although my knowledge of AppleScript is very limited. However, what I want the most is the offset of the movie "Current Time" to convert to timestamps for recording a subtitle script.

The following simple method shows the exact current position in (float) seconds in a dialog box, but I would really like AppleScript to return a variable to me which I can use in the rest of the application. How can I change the code below to do this? Is it possible to access this value? Thanks for the million in advance :-)

-(IBAction)currentPlayTime:(id)sender { NSString *scriptString=[NSString stringWithFormat: // get time of current frame... (works perfectly)! @"tell application \"QuickTime Player\"\n" @"set timeScale to 600\n" @"set curr_pos to current time of movie 1/timeScale\n" @"display dialog curr_pos\n" // ...not in a practical form to use @"end tell\n"]; NSDictionary *errorDict= nil; NSAppleScript *appleScriptObject=[[NSAppleScript alloc] initWithSource:scriptString]; NSAppleEventDescriptor *eventDescriptor=[appleScriptObject executeAndReturnError: &errorDict]; // handle any errors here (snipped for brevity) [appleScriptObject release]; // can I retain this? } 
+7
source share
3 answers

Here is the corresponding AppleScript that you want to run:

 property timeScale : 600 set currentPosition to missing value tell application "QuickTime Player" set currentPosition to (current time of document 1) / timeScale end tell return currentPosition 

If you are not familiar with it, property is a way to specify a global variable in AppleScript. In addition, the missing value is the equivalent of AppleScript nil in Objective-C. So this script first defines a variable called currentPosition and sets the value to missing value . He then enters the tell block, which, if successful, will change the currentPosition variable. Then, outside the tell block, it returns the currentPosition variable.

In Objective-C code, when creating an NSAppleScript with the above code, its -executeAndReturnError: method returns the currentPosition variable in NSAppleScriptEventDescriptor .

 -(IBAction)currentPlayTime:(id)sender { NSDictionary *error = nil; NSMutableString *scriptText = [NSMutableString stringWithString:@"property timeScale : 600\n"]; [scriptText appendString:@"set currentPosition to missing value\n"]; [scriptText appendString:@"tell application \"QuickTime Player\"\n "]; [scriptText appendString:@"set currentPosition to (current time of document 1) / timeScale\n"]; [scriptText appendString:@"end tell\n"]; [scriptText appendString:@"return currentPosition\n"]; NSAppleScript *script = [[[NSAppleScript alloc] initWithSource:scriptText] autorelease]; NSAppleEventDescriptor *result = [script executeAndReturnError:&error]; NSLog(@"result == %@", result); DescType descriptorType = [result descriptorType]; NSLog(@"descriptorType == %@", NSFileTypeForHFSTypeCode(descriptorType)); // returns a double NSData *data = [result data]; double currentPosition = 0; [data getBytes:&currentPosition length:[data length]]; NSLog(@"currentPosition == %f", currentPosition); } 

You can extract the contents of NSAppleEventDescriptor as shown above.

Using the Bridge scripting infrastructure has a slight learning curve, but will allow you to work with native types such as NSNumber , instead of taking the somewhat dirty path of extracting raw bytes from the AppleEvent descriptor.

+17
source

Use Script Bridge . This is the bridge between AppleScript and Objective-C, and other applications (like QuickTime Player) are presented as Objectve-C objects in your code. Thus, you do not need to create AppleScript code manually.

Some say AppScript is better than Scripting Bridge.

+1
source

NSAppleEventDescriptor has some methods for converting to some objective-C types, if you go to my website and upload an NDScript project, it has the NSAppleEventDescriptor category, which adds a lot more methods to force objective-C type. You can use this category without the rest of the project. http://homepage.mac.com/nathan_day/pages/source.xml

+1
source

All Articles