【发布时间】:2010-03-19 18:11:55
【问题描述】:
我是 Cocoa 编程领域的新手,我想为我的应用程序添加 Applescript 支持。 Apple 网站上的示例似乎已过时。
如何向我的 Cocoa 应用程序添加 Applescript 支持?
【问题讨论】:
-
不清楚这个问题是关于使应用程序可编写脚本还是从应用程序调用脚本。
标签: objective-c cocoa applescript
我是 Cocoa 编程领域的新手,我想为我的应用程序添加 Applescript 支持。 Apple 网站上的示例似乎已过时。
如何向我的 Cocoa 应用程序添加 Applescript 支持?
【问题讨论】:
标签: objective-c cocoa applescript
如果您想从应用程序发送 AppleScript 并需要沙盒应用程序,则需要创建临时授权
您需要在 info.plist 中添加这两个键
<key>NSAppleScriptEnabled</key>
<true/>
<key>OSAScriptingDefinition</key>
<string>MyAppName.sdef</string>
...当然,您必须将“MyAppName”更改为您的应用名称
创建一个 .sdef 文件并将其添加到您的项目中。 现在进一步的课程很大程度上取决于您的应用程序的需要,有:
-
去这里找到详细的描述和许多关于他们实现的细节:https://developer.apple.com/library/content/documentation/Cocoa/Conceptual/ScriptableCocoaApplications/SApps_script_cmds/SAppsScriptCmds.html
我发现使用 Class 和 KVC Elements 非常复杂,因为我只想执行一个命令,没什么特别的。因此,为了帮助其他人,这里有一个示例,说明如何使用一个参数创建一个新的简单 command。在这个例子中,它会像这样“查找”一个字符串:
tell application "MyAppName"
lookup "some string"
end tell
此命令的 .sdef 文件如下所示:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE dictionary SYSTEM "file://localhost/System/Library/DTDs/sdef.dtd">
<dictionary title="MyAppName">
<suite name="MyAppName Suite" code="MApN" description="MyAppName Scripts">
<command name="lookup" code="lkpstrng" description="Look up a string, searches for an entry">
<cocoa class="MyLookupCommand"/>
<direct-parameter description="The string to lookup">
<type type="text"/>
</direct-parameter>
</command>
</suite>
</dictionary>
创建一个 NSScriptCommand 的子类并将其命名为 MyLookupCommand
MyLookupCommand.h
#import <Foundation/Foundation.h>
@interface MyLookupCommand : NSScriptCommand
@end
MyLookupCommand.m
#import "MyLookupCommand.h"
@implementation MyLookupCommand
-(id)performDefaultImplementation {
// get the arguments
NSDictionary *args = [self evaluatedArguments];
NSString *stringToSearch = @"";
if(args.count) {
stringToSearch = [args valueForKey:@""]; // get the direct argument
} else {
// raise error
[self setScriptErrorNumber:-50];
[self setScriptErrorString:@"Parameter Error: A Parameter is expected for the verb 'lookup' (You have to specify _what_ you want to lookup!)."];
}
// Implement your code logic (in this example, I'm just posting an internal notification)
[[NSNotificationCenter defaultCenter] postNotificationName:@"AppShouldLookupStringNotification" object:stringToSearch];
return nil;
}
@end
基本上就是这样。这样做的秘诀是继承 NSScriptCommand 并覆盖 performDefaultImplementation。我希望这可以帮助某人更快地获得它...
【讨论】:
NSScriptCommand 子类中简单地使用 self.directParameter。
<cocoa class="MyAppName.MyLookupCommand"/>
现代版本的 Cocoa 可以直接解释脚本定义 (.sdef) 属性列表,因此您需要为基本 AppleScript 支持做的就是根据文档创建 sdef,将其添加到“复制捆绑资源”阶段,然后在 Info.plist 中声明 AppleScript 支持。要访问 NSApp 以外的对象,您需要定义对象说明符,因此每个对象都知道它在脚本世界层次结构中的位置。这使您可以对对象属性进行 kvc 操作,并能够将对象方法用作简单的脚本命令。
【讨论】:
一个简单的例子让你开始,
将脚本(命名对话框)放入文档文件夹,然后您可以从 Xcode 运行它
NSArray *arrayPaths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *docDirectory = [arrayPaths objectAtIndex:0];
NSString *filePath = [docDirectory stringByAppendingString:@"/dialog.scpt"];
NSAppleScript *scriptObject = [[NSAppleScript alloc] initWithContentsOfURL:[NSURL fileURLWithPath:filePath] error:nil];
[scriptObject executeAndReturnError:nil];
将脚本保留在外部的好处是能够在 Xcode 之外对其进行编辑。 如果您确实开始编辑,我建议您添加错误检查,因为 applescript 可能无法编译
也许检查一下
if(scriptObject.isCompiled){
【讨论】: