如何从Scripting Bridge执行等效的AppleScript“复制”命令?

时间:2010-07-20 18:21:33

标签: objective-c applescript scripting-bridge

有没有办法在Scripting Bridge的容器中进行远程复制?在AppleScript中,这看起来像是“将[容器]复制[元素]到[容器中的位置]”。例如,在告诉TextEdit文档的上下文中,您可以“将其文本的第一段复制到其文本的末尾”,将第一段复制到文档的末尾,同时保留所有格式。

使用Scripting Bridge从Objective-C有什么办法吗?

我试过这样的事情:

SBObject* foo = [container objectAtIndex: 0];
[container addObject: foo];

收到消息“无法添加已存在的对象”。在控制台上;看来addObject和各种replace*方法仅在您构建新的SBObject实例并插入时才有效。

1 个答案:

答案 0 :(得分:1)

当AppleScript的内置copy命令的第二个参数是应用程序引用时,AppleScript“帮助”对应用程序duplicateset命令进行别名,具体取决于第一个参数是另一个参考。为避免混淆,最好在AppleScript中处理脚本化应用程序时明确使用duplicateset

对于SB,您需要在头文件中查找duplicate...方法。请注意,SB的duplicate命令是半残缺的(SB has quite a few shortcomings),因为它一次只能处理单个对象。大多数应用程序允许您在单个命令中操作多个对象(告诫其脚本支持中的任何错误),例如AppleScript会让你说:

tell application "iTunes"
    duplicate (every track whose artist is "Foo") to (playlist "Bar")
end tell

但SB不会;相反,你必须提取单个引用的列表并迭代它们,一次处理一个。使您的代码变得更长,如果您在其他地方有大量对象,则效率可能非常低。

另一个选项是objc-appscript,它可以正确地完成所有这些工作,并且不太容易出现应用程序兼容性问题(正如Matt Neuburg所说的那样,'quirk-for-quirk compatibility')。另外,你得到了ASTranslate,它将AppleScript命令转换为等效的Python / Ruby / ObjC语法 - 在弄清楚如何正确地命令命令时非常方便:

#import "ITGlue/ITGlue.h"
ITApplication *itunes = [ITApplication applicationWithName: @"iTunes"];
ITReference *ref = [[itunes tracks] byTest: [[ITIts artist] equals: @"Foo"]];
ITDuplicateCommand *cmd = [[ref duplicate] to: [[itunes playlists] byName: @"Bar"]];
id result = [cmd send];

另一种选择,如果您使用的是10.6,则可以使用AppleScriptObjC桥,它允许您在同一个程序中组合AS和ObjC,而不会产生任何令人讨厌的NSAppleScript废话。这将允许您使用AppleScript最好的(与其他应用程序通信)和ObjC用于其他一切。官方文档is limited,但网络搜索应该抛出各种第三方资源。 MacScripter.net可能是一个很好的起点 - 除了ASOC论坛之外,Craig Williams在一段时间后发布了一系列教程。

(顺便说一下,克雷格还在第三版Apress的学习AppleScript中贡献了一篇关于ASOC的章节,这是我共同编写的,其中包含许多关于应用程序脚本原则和实践的信息,包括set /的澄清duplicate / copy。)

相关问题