Applescript调用Cocoa App Method?

时间:2014-04-21 20:26:02

标签: objective-c cocoa methods 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,调用的方法是&#34; GoToNext:&#34;

这是我的.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编辑器阅读苹果脚本词典时, 我可以读取sdef文件,但是当我制作像

这样的AppleScript时

告诉应用程序&#34;实时控制      session gotonext 结束告诉

我得到一个错误,说&#34; gotonext&#34;变量未定义。

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

1 个答案:

答案 0 :(得分:0)

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

因此,首先,AppleScript 中的 class 意味着应用程序中的可编写脚本的对象类型。当您使用 '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”这样的组合。见Scripting Interface Guidelines

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

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

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