Objective c 在Obj-C中获取AppleScript返回值

Objective c 在Obj-C中获取AppleScript返回值,objective-c,applescript,Objective C,Applescript,我在我的Obj-C可可项目中使用了一些AppleScript来控制QuickTime播放器(播放、暂停、停止、向前和向后慢跑等),取得了巨大的成功,尽管我对AppleScript的了解非常有限。 然而,我最想要的是将电影的“当前时间”偏移量转换为时间戳以编写字幕脚本 下面的简单方法在对话框中以(浮点)秒为单位显示精确的当前位置,但我真的希望AppleScript返回一个变量,我可以在应用程序的其余部分中使用。我如何修改下面的代码才能做到这一点?甚至可以访问此值吗?提前感谢100万:-) 使用。这

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

下面的简单方法在对话框中以(浮点)秒为单位显示精确的当前位置,但我真的希望AppleScript返回一个变量,我可以在应用程序的其余部分中使用。我如何修改下面的代码才能做到这一点?甚至可以访问此值吗?提前感谢100万:-)

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


有人说它比编写脚本桥更好

以下是您希望运行的相应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
等价的AppleScript。因此,该脚本首先定义一个名为
currentPosition
的变量,并将该值设置为
missing value
。然后进入
tell
块,如果成功,将改变
currentPosition
变量。然后,在tell块之外,它返回
currentPosition
变量

在Objective-C代码中,当您使用上述代码创建
NSAppleScript
时,其
-executeAndReturnError:
方法将在
NSAppleScript事件描述符中返回
currentPosition
变量

-(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
的内容,如上所示


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

NSAppleEventDescriptor有一些方法可以转换为某些objective-C类型,如果你去我的网站下载NDScript项目,它有一个NSAppleEventDescriptor类别,它为Objective-C类型添加了更多的强制方法。您可以在不使用项目其余部分的情况下使用该类别。

你好,Yuji。脚本桥似乎是最简单、最优雅的解决方案。成功运行了iTunes测试,但令人惊讶的是(除非我做错了什么),它似乎没有QT播放器功能!无法使用sdef/stp创建必要的头文件。。。苹果的“ScriptingBridgeConcepts.pdf”一次也没有提到QT播放器。网上也没有关于脚本桥和QT的信息。我还将研究AppScript,但这还需要几天时间。谢谢你的帮助:-)你好,内森。感谢捆绑包为您的NDScript项目提供链接/下载,我将在下周对其进行修补。看起来你已经投入了大量的精力。。。感谢您的输入:-)我将把NSAppleEventDescriptor类别拆分出来,并将其放到GitHub上,因为很多人使用该类别,而不使用NDScript的其余部分。NDScript的许多原因不再适用于NSAppleScript和脚本桥,您可以使用它在线程中运行脚本,我正在为我编写的一个应用程序开发它,我希望允许用户使用AppleScripts覆盖内部类并更改其工作方式。请关注我的GitHub存储库,我将在本周完成它。如果您仍然感兴趣,我已经在我的GetHub上为NSAppleEventDescriptor类别添加了一个单独的存储库。[nathanday][}Hi Nsgood.是的!它就像一个符咒一样工作:-)正如你所怀疑的,我不熟悉AppleScript的'property'变量,并且对一般情况知之甚少,除了在我的代码中使用奇怪的、粗糙的代码片段,这已经完成了工作。另外(如Yuji所说)脚本桥本来是一种简单而优雅的方式,我可以使用熟悉的数据类型,但我似乎无法将其应用于QT Player,除非我忽略了一些事情(或做了一些愚蠢的事情)。我将继续在“网上”搜索解决方案。同时再次感谢。感谢您的输入:-)
-(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);
}