为了存储对象的值以供外部(外部 AS)访问,我需要能够获取该对象的每个属性,然后我会尝试将其强制转换为文本并将其存储在某个地方。
如何获取对象拥有的属性列表。例如,我可以这样写:
tell me
get properties
end tell
适用于 script 对象。
但是对于许多其他对象,我只是得到一个错误,例如“描述符类型不匹配”,如下所示:
tell application "iTunes"
get properties of file track 1
end tell
现在,我知道出色的 Script Debugger 可以做到这一点(它可以显示任何对象的整个属性集),所以它也应该可以用书面的 AppleScript 实现。这有什么秘密吗?
Script Debugger 的作者 Mark Alldritt 非常友好地向我解释了“秘密”。
Script Debugger 使用一些特殊的 AppleScript API 函数,包括 OSAGetPropertyNames(),来获取此信息。
因此,如果我用 C 语言编写一个包装器,我也可以做到这一点。
更新
Cocoa 脚本 API 有专门的类(
NSScriptSuiteRegistry
和 NSScriptClassDescription
)——框架通过读取应用程序的脚本定义 (.sdef) 文件构建此信息。有了它,所有可用的类及其属性都可以很容易地学习。
Script Debugger 是 Applescript,只是围绕它放置了一堆编程工具。但是“描述符类型不匹配”真的不应该进入它。你能展示你的代码吗,因为这在脚本编辑器中工作得很好:
tell application "Finder"
set theFile to choose file
get properties of theFile -- the "return" keyword also works here as well
end tell
不同的应用程序会有不同的表现,但没有示例代码,变化太多无法确定。
更新每条评论和更新的问题: 同样,不同的应用程序表现不同。应用程序实际上必须具有
properties
属性才能将记录返回给您(尽管有时这与可以从对象获得的其他信息不同)。通常,这是在根类中实现的——在大多数情况下item
; iTunes 不允许这样做。甚至 Script Debugger 也无法解决这个问题。
您可以使用一个技巧,因为您可以强制 Applescript 告诉您错误,并且此文本包含作为目标的对象的属性。
set myThing to {FirstName:"Fred", LastName:"Smith"}
ListProperties(myThing)
on ListProperties(MyObject)
try
get properties of MyObject
on error errText number errNum
set pStart to offset of "{" in errText
set structure to text pStart thru ((length of errText) - 2) of errText
set TIDL to AppleScript's text item delimiters
set AppleScript's text item delimiters to ","
set fields to text items of structure as list
set myMessage to ""
repeat with f from 1 to count of fields
set AppleScript's text item delimiters to ":"
set theseItems to text items of (item f of fields) as list
set itemPropName to text 2 thru length of item 1 of theseItems
set itemValue to item 2 of theseItems
set myMessage to myMessage & "Property Label: " & itemPropName & tab & "Value: " & itemValue & linefeed
end repeat
set AppleScript's text item delimiters to TIDL
display dialog myMessage
end try
end ListProperties
应用程序返回“properties”属性的能力一直存在,但在 Cocoa 之前比之后花费了更多的工作。在 Cocoa 之前,开发人员必须构建一个 AEList 结构,其中填充了每个属性的键和值,然后在 typePropertyList 描述符中返回它。许多开发人员没有打扰。使用 Cocoa Scripting,只要您对类的所有属性使用符合 KVC 的名称,并且在 SDEF 文件中正确配置了术语和 cocoa-keys,您基本上就可以免费获得它。
顺便说一句,在 2016 年,iTunes 12.3.3,
tell application "iTunes" to get properties of file track 1
正确返回一长串属性。
这里说了很多话,但没说主要的。 为什么属性可能适用于某些对象但可能不适用于其他对象?
因此,无论 Cocoa 应用程序是否可编写脚本,它都会响应标准套件中的命令和属性。在 Standard Suite 中,properties 属性是 Standard Suite 的“item”类的属性,可用于以下类的对象(项目):
应用程序、属性运行、字符、单词、段落、颜色、文本、 文档、窗口
除了上面列出的对象之外,一些脚本应用程序还有一个额外的properties属性,它是应用程序套件的“item”类的属性。此属性的可用性取决于特定的应用程序。例如,Music.app 应用程序,除了上面列出的对象之外,还允许您请求以下对象的属性:
Airplay 设备、艺术品、编码器、EQ 预设、播放列表、源、轨道、视觉。
也就是说,答案是这样的:您可以在脚本中获取应用程序允许的第 1 组和第 2 组中的那些对象的属性。