【问题标题】:How to call a Cocoa App Method by AppleScript?如何通过 AppleScript 调用 Cocoa App 方法?
【发布时间】:2014-06-05 23:46:03
【问题描述】:

我制作了一个应用程序,它只有一个调用方法的按钮。我想实现调用此方法的 AppleScript 可能性。

我阅读了 Apple 文档并在我的项目中创建了一个 *.sdef 文件,但问题如下:

我不明白 NSScriptCommand 的对象制作,我只想调用我项目中现有的方法,我该怎么做?

这是我的 sdef 文件:

    <?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE dictionary SYSTEM "file://localhost/System/Library/DTDs/sdef.dtd">
<dictionary title="Live Control">
    <suite name="Live Control Suite" code="LivC" description="Live Control Scripts">
        <class name="session" code="sess" description="OTN Telnet Control">
            <cocoa class="NTLAppDelegate"/>
            <responds-to name="gotonext">
                <cocoa method="GoToNextFromScript:"/>
            </responds-to>
        </class>
    </suite>
</dictionary>

所以我告诉我使用的类是 NTLAppDelegate,调用的方法是“GoToNext:”

这是我的 .h 文件:

#import <Cocoa/Cocoa.h>

@interface NTLAppDelegate : NSObject <NSStreamDelegate> {

    NSInputStream * InputStream;
    NSOutputStream * OutputStream;
    unsigned char IACcommand[12];

}

- (IBAction)GoToNextButton:(id)sender;
- (id) GoToNextFromScript:(NSScriptCommand *)command;

@property (assign)

IBOutlet NSWindow * TheMainWindow;

@end

还有我的 *.m 文件:

#import "NTLAppDelegate.h"

@implementation NTLAppDelegate
    
// GoToNext

- (id)GoToNextFromScript:(NSScriptCommand *)command {
    
    [ConnectLog setEditable:YES];
    [ConnectLog setString:@"APPLE SCRIPT TEST"];
    [ConnectLog setEditable:NO];
    
    return nil;
    
}

- (IBAction)SkipToNextButton:(id)sender {
    
    [ConnectLog setEditable:YES];
    [ConnectLog setString:@""];
    [ConnectLog setEditable:NO];
    
    CFReadStreamRef readStream;
    CFWriteStreamRef writeStream;
    CFStreamCreatePairWithSocketToHost(NULL, (__bridge CFStringRef)[HostField stringValue], [PortField intValue], &readStream, &writeStream);
    InputStream = (__bridge NSInputStream *)readStream;
    OutputStream = (__bridge NSOutputStream *)writeStream;
    
    [InputStream setDelegate:self];
    [OutputStream setDelegate:self];
    
...... rest is the code for the tcp stream control (input and output) not concerned .....

}

@synthesize TheMainWindow = _window;

- (void)applicationDidFinishLaunching:(NSNotification *)aNotification {
    
}

@end

所以,没有任何效果...当我使用 Apple 脚本编辑器阅读 Apple 脚本字典时, 我可以读取 sdef 文件,但是当我制作类似的 AppleScript 时

告诉应用程序“实时控制 会话 gotonext 结束告诉

我收到一个错误,提示“gotonext”变量未定义。

如果有人能解释我如何写这个小东西,那就太好了。 请注意,老实说,我的 Obj-C / C++ 知识很差, 但我的应用程序正在运行(只是一个带有一个按钮的可可应用程序,它打开一个 tcp 套接字,将 IAC 命令发送到 telnet 会话并编写一个命令)。我只需要 AppleScript 控件就可以了。

【问题讨论】:

    标签: objective-c cocoa methods applescript


    【解决方案1】:

    您的设置方式存在一些问题。你真的很想阅读Cocoa Scripting Guide,看看旧的但仍然有用的Shadowlab SDEF Reference

    因此,首先,AppleScript 中的 class 意味着应用程序中的可编写脚本的对象类型。当您使用“类”块定义 AppleScript 对象时,&lt;cocoa class="..."&gt; 旨在指向您编写的包含您指定的属性的类。默认情况下,所有 Apple 事件都由 AppDelegate 处理,因此您永远不需要将其指定为一个类(并且没有任何意义:“Application”是 SDEF 中由“Application”类定义的单独对象可可标准套房)。在你的情况下,你可能想要这样的东西:

    <class name="session" code="sess" description="OTN Telnet Control">
        <cocoa class="NTLTelnetSession"/>
    

    然后你会想要编写一个名为“NTLTelnetSession”的可可类,其中包含你感兴趣的 telnet 会话的所有属性的实例变量。你还需要在 AppDelegate 中添加一个数组来保存实例化的对象,告诉应用程序委托它将处理“NTLTelnetSession”键,并添加对象说明符方法,以便脚本事件可以在对象层次结构中上下移动:请参阅脚本指南了解更多信息。

    其次,您需要向 SDEF 添加一个“命令”块,以便 CocoaScripting 识别您想要的命令。这看起来像:

    <command name="go to nest" code="LivCGoTN" description="Move an object to a new location.">
    </command>
    

    请注意,名称应该(按照惯例)写成可以在标准英语句子中用作动词短语;不鼓励使用像“gotonext”这样的复合材料。见Scripting Interface Guidelines

    您有两个命令选项:object firstverb first 区别在于 object first 命令是您的 AppleScript 对象知道如何为自己做,而 verb first 命令是应用程序对对象所做的事情。在您的情况下,这意味着这些选项:

    • 对象优先:像您在帖子中所做的那样使用responds-to 块,并在您的 NTLTelnetSession 类中(而不是在应用程序委托中)用给定的名称编写一个神话。这意味着 telnet 会话对象需要知道 'next' 指的是什么,并返回正确的信息
    • 动词优先:要么:
      1. 在应用委托中编写一个具有适当签名的方法,该方法将自行处理命令,或者...
      2. &lt;cocoa class="NTLGoToNextCommand"/&gt; 元素添加到“命令”块中,然后编写一个名为“NTLGoToNextCommand”的类并实现performDefaultImplementation 方法。

    您可以使用这两种方法,例如,如果您有一个通用命令,某些对象知道如何处理而其他对象不知道。如果可用,Cocoa 脚本将始终选择对象优先命令。但实际上,您应该按照自己的方式学习 Cocoa 脚本指南:它是在您的应用程序中实现脚本的编写不佳的黄金标准。

    【讨论】:

      猜你喜欢
      • 2011-05-30
      • 1970-01-01
      • 1970-01-01
      • 2012-04-11
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-01-08
      相关资源
      最近更新 更多