繁体   English   中英

如何通过 AppleScript 调用 Cocoa App 方法?

[英]How to call a Cocoa App Method by AppleScript?

我制作了一个应用程序,它只有一个调用方法的按钮。 我想实现 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 Script 编辑器阅读 Apple 脚本字典时,我可以读取 sdef 文件,但是当我制作 AppleScript 时

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

我收到一条错误消息,指出未定义“gotonext”变量。

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

您如何设置事物存在一些问题。 您真的很想阅读Cocoa Scripting Guide ,并查看旧的但仍然有用的Shadowlab SDEF Reference

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

<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”这样的组合。 请参阅脚本接口指南

命令有两个选项:对象优先动词优先区别在于对象优先命令是 AppleScript 对象知道如何为自己做的事情,而动词优先命令是应用程序对对象执行的操作。 在您的情况下,这意味着这些选项:

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

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM