Sea*_*ris 4 smalltalk objective-c objective-c-runtime pharo scripting-bridge
上下文:我正在开发Pharo/Smalltalk -> Objective-C 桥
场景:在以下 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]
Run Code Online (Sandbox Code Playgroud)
问题:桥用于class_getInstanceMethod确定对象是否理解消息/选择器,但对于脚本消息,如playpause
问题#1
为什么class_getInstanceMethod像这样的脚本消息会返回 NULL playpause?同样的问题class_copyMethodList?脚本消息有什么特别之处,它们的行为与其他 Obj-C 消息不同(除非它们这样做!)?
问题 #2 [已解决 - 请参阅@Matt 的回答]
根据文档,SB 在“iTunes 应用程序的动态定义子类”中放置了“自动处理 Apple 事件发送的应用程序特定方法”?并且,鉴于class_getInstanceMethod无法找到这种行为(见下文),桥接器测试它的可靠方法是什么(即是否存在这样的方法/消息)?
Objective-C 运行时 API 报告的结果好坏参半。一方面,该类iTunesApplication似乎没有任何方法(或与此相关的属性):
class_copyMethodList([iTunes class]...返回零的方法class_getInstanceMethod桥接器用来查找和执行方法的 失败。另一方面,#playpause可以通过API的其他部分进行查询和发送:
respondsToSelector:-> 正确methodSignatureForSelector:返回签名performSelector:实际发送消息奇怪的是,在 Obj-C 中methodForSelector:@"playpause"成功返回一个IMP,但如果从桥的另一边发送则崩溃。
问题 #3 [已解决]
如何模拟/复制[3]?
@Willeke 在评论中回答:[iTunes sendEvent:'hook' id:'PlPs' parameters:0]
\n\n\n如果 SB 不使用 Objective-C 消息,那么文档中“SBApplication 的子类实现自动处理 Apple 事件发送的应用程序特定方法”是什么意思?为什么 iTunes respondsToSelector: @"playpause" 会返回 true?[iTunes 播放暂停] 是如何工作的?等等等等。
\n
它之所以有效,是因为您在脚本桥应用程序中所做的第一件事就是生成标头。在 Catalina 中你可以这样做:
\n\nsdp -f h --basename iTunes /System/Applications/Music.app/Contents/Resources/com.apple.Music.sdef\nRun Code Online (Sandbox Code Playgroud)\n\n这会读取 iTunes 字典 ( sdef) 并生成一组类似 Objective-C 类的标头。现在您有了一个iTunes.h文件,您可以将其包含在应用程序项目中并导入到代码中。它包含这一行:
- (void) playpause; // toggle the playing/paused state of the current track\nRun Code Online (Sandbox Code Playgroud)\n\n因此,nowplaypause被显式声明为可以发送到 iTunesApplication 对象的合法命令。然后,当您实际运行应用程序时,您会说
iTunesApplication* tunes = (iTunesApplication*)[SBApplication applicationWithBundleIdentifier:@"com.apple.music"];\nRun Code Online (Sandbox Code Playgroud)\n\n这会导致您的应用程序与 iTunes(音乐)对话并再次sdef获取字典 ( ) ,从而生成标头中声明的方法的实现。该命令的实现正如其所说:即将事件发送到 iTunes。playpausesdefhookPlPs
这既解释了为什么你被允许说话 playpause,也解释了当你说话时会发生什么。
这就是AppleScript的\xe2\x80\x94,它是一个应用程序,提供了您可以使用Apple 事件对其说出的内容的列表,以及引用这些Apple 事件的类似英语的术语。
\n\n因此,如果您想编写一个桥接器,则必须做同样的事情:您需要提供一种方法来搜索目标应用程序的资源,并将该信息转换为以您的sdef语言给出相应命令的方法,无论它是什么语言是。
| 归档时间: |
|
| 查看次数: |
547 次 |
| 最近记录: |