【问题标题】:Scriptability (AppleScript) in a Mac Carbon applicationMac Carbon 应用程序中的可编写脚本 (AppleScript)
【发布时间】:2016-03-15 23:34:15
【问题描述】:

我正在尝试向我的非 Cocoa 应用程序添加 AppleScripting 支持。

我正在处理诸如 AEGetParamDesc 之类的低级函数,我自己处理 form / want / seld 参数。

我的词汇表提供了一个类,我们称之为“图像”。它有一个属性“name”。

我已经得到了一些 Applescript 代码,例如:

get Images
get name of every Image
get count Images
get every Image
get first Image
get Image 1

因此,基本上,访问对象及其属性都有效。

但是,当我尝试这些类似的访问表单时,它们都失败了:

get Images whose name = "foo"

repeat with img in Images
end repeat

在第一种情况下,看来我必须处理test 表单。

在第二种情况下,计数运算符 (cnte) 不直接请求类对象,而是使用描述索引对象的 cobj 运算符。

这一切都让我想知道这会走多远。我是否必须在我的代码中单独实现 Applescript 的所有可能语法和运算符?我假设“谁的”运算符会简单地将“每个图像”和“图像 x 的名称”的请求组合起来,就像我可以在 Applescript 中单独编写它们一样,而不是为每个图像使用不同的 AppleEvent 公式。

whose <boolean-test> 也一样。为什么 AppleScript 不简单地执行 name = "foo" 本身的相等性测试,因为它是一个根本不需要涉及我的应用程序代码的文本比较?

我有什么遗漏吗?我可以将这些转发给我还不知道的 AE 功能,还是我必须自己处理所有可能的比较和流控制命令?

【问题讨论】:

    标签: applescript macos-carbon


    【解决方案1】:

    Thomas Tempelmann(以 Find Any File 闻名?),如果你真的不能在 Cocoa 中重写应用程序,这里是我多年前写的一篇文章,其中详细介绍了可可之前的可编写脚本(用 C 语言)编码,包括处理您在上面询问的表单谁。

    http://www.mactech.com/articles/develop/issue_28/reuter.html

    这篇文章由 Apple 在其 Develop 杂志上发表,其中包含我为名为“Sketch”的示例应用程序编写的源代码。这是在 Apple 发布自己的示例项目(也称为“Sketch”)之前的几年。如果对你有帮助,我还有源代码。

    祝你好运!

    【讨论】:

    • 是的,我是 FAF 的作者,实际上是在尝试添加 Scriptability复杂的东西。我会对使用古老 API 的旧版本非常感兴趣。我现在看一下链接的文章,也许这已经是我所需要的了。
    • 嗯,虽然文章一般处理“谁”这个词,但似乎没有任何特定的代码来处理测试(例如“is”和“=”)。但是我看到了对 AEResolve 的调用,到目前为止我自己还没有使用过。我想知道AEResolve是否对我有用?很难弄清楚苹果已经删除了所有这些旧文档。需要做更多的挖掘工作。
    • 前 Cocoa AS 引擎对您必须安装的处理程序使用了回调机制,其中 AEResolve 有点像切换终端,不断请求令牌,然后使用该令牌调用您的方法等,直到它获得包含请求数据的请求类型的令牌。这需要很多粗糙的代码,包括 AETE 资源,但一旦你掌握了它的窍门,它是可行的。在 Cocoa 中通常要容易得多,它使用通过字符串查找调用类和方法的魔力,因此 AS 术语到 Cocoa 方法的映射在 SDEF 中更加清晰。
    • Thomas,formWho的解析在文章的“处理formTest和formWhose”中有讨论,示例代码中用于处理其测试的两个方法是OSLCountObjectsCallback和OSLCompareObjectsCallback,都在OSLHelpers.c中.其解决方法基本上是通过检查所需类的每个对象并检查所请求的一个或多个属性以获得所请求的值来完成的。它很像实现一个面向对象的“equals”方法,当且仅当指定的字段子集相等时,两个对象才被认为相等。结果是一个列表。
    • 让我开始思考,所以我发现了我的可编写脚本的文本编辑器 Ted 无需任何特殊代码即可处理 formWho。例如,“获取大小为 24 的单词”使用直接参数调用内部 Get 命令:
    【解决方案2】:

    Apple 事件对象模型专为操作系统(系统 7)上的高延迟 IPC 而设计,每秒最多可进行 60 次上下文切换。可以对多个对象进行操作的复杂查询和过程允许使用更少的跨进程消息来完成更多的工作。此外,它被设计成一个相对厚实的 View-Controller 抽象,强调 UI/UX,将用户数据的理想化视图呈现为关系图,而不管底层数据如何实际存储或复杂或难于存储实现 VC 代码以从一个映射到另一个可能。 AEOM 与关系数据库的共同点比 OOP 世界中的任何东西都多,而与 Apple 事件 IPC 最接近的类比是通过 XML-RPC 发送 XQueries。背景见:

    http://www.cs.utexas.edu/~wcook/Drafts/2006/ashopl.pdf

    当然,如今,OS X 每秒可以进行数千次进程切换而不会费力,因此不必为了获得可接受的性能而实施复杂的 AE 视图控制器。 TBH,我建议您节省自己的时间并实现最简单的 RPC,它工作简单、可靠且快速。将改变状态的处理程序限制为在每条消息上对单个对象进行操作(因为在数组上执行 Set 操作很难正确),实现定位对象所需的最简单的查询表单,并返回基本上充当安全指针的按 ID 说明符以前识别的对象,因此用户可以使用更多命令快速操作它们,而无需重复往返复杂的完整查询。

    哦,除非您有特定的理由使用 C,否则我建议您仅使用 NSAppleEventDescriptor 和 NSAppleEventManager。自 10.6 以来,C Apple 事件管理器 API 是古老的、粗糙的和遗留的,因此不推荐用于新的开发。您可能(重复,可能)甚至找到一种方法来使用一些 Cocoa 脚本类来完成一些繁重的工作。对象说明符,虽然 CS 本身非常糟糕并且与 ApplicationKit 高度耦合,所以除非它确实有帮助,否则不要浪费时间搞乱它(CS 之前已经埋葬了更好的项目)。

    当然,另一件事是整个 Mac 自动化生态系统处于完全垂死的状态,在当前的管理下不太可能变得更好,因此从划痕不再存在。如果“简单、快速、安全和愚蠢”对于您希望吸引的任何用户都“足够好”,那就这样做吧。

    【讨论】:

    • 感谢您提供背景信息。我还考虑过通过 Automator Action 插件提供对我的应用程序数据的访问,但这看起来也不太容易,因为缺乏在我正在运行的应用程序和 Action 插件之间传输数据的简单方法。不,它不是用 C 语言制作的,而是用 Xojo(以前的 REALbasic)制作的,所以我必须在这里处理另一层复杂性,并且需要使用我必须处理的自定义方法进行子类化的动态对象越少,它应该越容易.除非 NS 类为我在问题中描述的类型做更多的工作。他们会吗?
    • 顺便说一句,我在哪里可以找到可编写脚本的应用程序可能遇到的所有 AE 相关代码的完整列表?我的意思是诸如 test、cobj 之类的代码。在当前的 Apple 开发文档中找不到它们,甚至没有谷歌搜索。是否有任何旧的 AppleScript 书籍涵盖应用程序端开发?它们似乎主要是为 AppleScript 用户编写的,而不是为应用程序开发人员编写的
    • 更新:旧的 Inside Mac 似乎包含类型代码。毕竟,十年前不应该把那些书送人!尽管如此,我还是不敢相信没有任何库或框架可以以更智能和通用的方式处理所有这些运算符。我不能成为第一个不得不处理这个问题的人。
    【解决方案3】:

    Apple 的 sample code for Sketch 提供了一个使用 Cocoa Scripting API 的好例子。

    示例代码不会对“repeat”和“whose”执行任何特殊处理,但它可以使用这些术语运行 AppleScript。

    这表明 Cocoa 脚本,即主要是 NSScriptObjectSpecifiers.h 中的类和协议,负责处理旧的 Carbon API 公开的复杂处理。

    因此,同样基于@foo 的回答,尝试基于NSObject(NSScriptObjectSpecifiers) 创建代理类,实现objectSpecifier 方法以及任何属性的get/set 访问器,然后使用能够在.sdef 文件中引用这些类。即使没有 Objective C,也可以使用 ObjC 运行时函数(例如 objc_registerClassPair)创建此类类。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2011-09-04
      • 1970-01-01
      • 1970-01-01
      • 2019-12-18
      • 1970-01-01
      • 1970-01-01
      • 2016-08-08
      相关资源
      最近更新 更多