我创建了一个只有一个调用方法按钮的应用程序。 我想实现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控件就可以了。)
答案 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' 指的是什么,并返回正确的信息<cocoa class="NTLGoToNextCommand"/>
元素,然后编写一个名为“NTLGoToNextCommand”的类并实现performDefaultImplementation
方法。您可以同时使用这两种方法,例如,如果您有一个通用命令,某些对象知道如何处理而其他对象不知道如何处理。如果可用,Cocoa Scripting 将始终选择对象第一个命令。但实际上,您应该按照自己的方式阅读 Cocoa 脚本指南:它是在您的应用中实现脚本编写的拙劣黄金标准。