在Obj-C中获取AppleScript返回值

时间:2011-07-24 02:08:33

标签: objective-c applescript

我在我的Obj-C可可项目中使用了一些AppleScript来控制QuickTime播放器(播放,暂停,停止,慢跑前进和后退等)并取得了巨大的成功,尽管我对AppleScript的了解非常有限。 但是,我最想要的是电影的“当前时间”偏移量,可以转换成用于编写字幕脚本的时间戳。

以下简单方法在对话框中显示(浮点)秒的精确当前位置,但我真的很喜欢AppleScript 返回 变量 我可以在app的其余部分使用。我怎么能修改下面的代码呢?甚至可以访问此值吗?提前一百万感谢: - )

-(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?
}

3 个答案:

答案 0 :(得分:17)

以下是您要运行的相应AppleScript:

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

如果您不熟悉它,property是一种在AppleScript中指定全局变量的方法。此外,missing value与Objective-C中的nil相当。因此,此脚本首先定义名为currentPosition的变量,并将值设置为missing value。然后它进入tell块,如果成功,将改变currentPosition变量。然后,在tell块之外,它返回currentPosition变量。

在Objective-C代码中,当您使用上述代码创建NSAppleScript时,其-executeAndReturnError:方法将返回currentPosition中的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);
}

您可以提取NSAppleEventDescriptor的内容,如上所示。

使用Scripting Bridge框架确实有一个轻微的学习曲线,但允许使用本地类型,如NSNumber,而不必采取从AppleEvent描述符中提取原始字节的“混乱”路线

答案 1 :(得分:1)

使用Scripting Bridge。这是AppleScript和Objective-C之间的桥梁,其他应用程序(例如QuickTime Player)在代码中表示为Objectve-C对象。因此,您不必手动构建AppleScript代码。

有人说AppScript比Scripting Bridge更好。

答案 2 :(得分:1)

NSAppleEventDescriptor有一些转换为某些Objective-C类型的方法,如果你去我的网站并下载NDScript项目,它有一个NSAppleEventDescriptor类别,它为Objective-C类型添加了更多强制方法。您可以在没有项目其余部分的情况下使用该类别。 http://homepage.mac.com/nathan_day/pages/source.xml