脚本桥--它是如何在 "幕后 "工作的?

问题描述 投票:0回答:1

上下文。我正在研究 a PharoSmalltalk -> Objective-C bridge

场景:在下面的Objective-C ScriptingBridge片段中。

iTunesApplication *iTunes = [SBApplication applicationWithBundleIdentifier:@"com.apple.iTunes"];

iTunesTrack *currentTrack = iTunes.currentTrack; //[1]
// This low level way works too
//iTunesTrack *currentTrack = [iTunes propertyWithCode: 'pTrk']; //[2]

[iTunes playpause]; //[3]

问题:该桥使用 class_getInstanceMethod 来确定一个对象是否理解一个消息选择器,但对于脚本消息,如 playpause

问题1为什么 class_getInstanceMethod 等脚本信息返回NULL playpause? 同样的问题 class_copyMethodList? 脚本消息有什么特别之处,它们的行为不像其他Obj-C消息(除了当它们这样做!)?

问题#2 [已解决 - 见 @Matt 的回答]

其中,根据 文献在 "为iTunes应用程序动态定义的子类 "中,SB是否放入了 "自动处理苹果事件发送的应用程序特定方法"?而且,鉴于 class_getInstanceMethod 找不到这种行为(见下文),那么桥有什么可靠的方法来测试它(即是否存在这样的方法消息)?

Objective-C Runtime API报告的结果参差不齐。一方面, iTunesApplication 类似乎没有任何方法(或属性)。

  • class_copyMethodList([iTunes class]... 返回零方法
  • class_getInstanceMethod,桥接器用来寻找和执行方法,但失败了。

另一方面 #playpause 可以通过API的其他部分进行查询和发送。

  • respondsToSelector: -> TRUE
  • methodSignatureForSelector: 返回一个签名
  • performSelector: 实际上是发送消息

奇怪的是。methodForSelector:@"playpause" 成功返回一个 IMP 在Obj-C中,但如果从桥的另一边发送,则会崩溃。

问题3 [已解决]

如何模拟[3]?

由 @Willeke 在评论中回答。[iTunes sendEvent:'hook' id:'PlPs' parameters:0]

objective-c smalltalk pharo objective-c-runtime scripting-bridge
1个回答
3
投票

如果SB不使用Objective-C消息,那么文档中所说的 "SBApplication的子类实现了特定于应用程序的方法,自动处理苹果事件的发送 "是什么意思?为什么iTunes respondsToSelector: @"playpause "工作,即返回true?还有[iTunes playpause]是如何工作的?等等,等等。

它的工作原理是 第一 在脚本桥应用程序中,你要做的是生成一个头。在Catalina中,你是这样做的。

sdp -f h --basename iTunes /System/Applications/Music.app/Contents/Resources/com.apple.Music.sdef

这将读取iTunes的字典sdef)并为一组类似的Objective-C类生成头。现在你有一个 iTunes.h 文件,您可以将其包含在应用程序项目中并导入您的代码中。它包含这一行。

- (void) playpause;  // toggle the playing/paused state of the current track

所以现在 playpause 被明确声明为一个合法的命令,你可以将其发送到iTunesApplication对象。然后,当你实际运行你的应用程序时,你说

iTunesApplication* tunes = (iTunesApplication*)[SBApplication applicationWithBundleIdentifier:@"com.apple.music"];

这将导致你的应用程序与iTunes(音乐)对话,并获得字典(sdef) 再次,产生 实施 的方法的实现。的实现。playpause 命令与 sdef 说,应该是:即发。hookPlPs 事件到iTunes。

所以,这既解释了为什么你被允许 playpause 和什么 发生 当你说的时候。

这就是 AppleScript - 它是一个应用程序,提供了一个列表,你可以使用苹果事件对它说,以及参考这些苹果事件的类似英语的术语。

所以如果 想写一个桥段,你必须做同样的事情:你需要提供一个搜刮的方法。sdef 的资源,并将这些信息转化为相应的命令,以便在目标应用程序的 你的 语言,无论它是什么。

© www.soinside.com 2019 - 2024. All rights reserved.