【问题标题】:How do I add Applescript support to my Cocoa application?如何将 Applescript 支持添加到我的 Cocoa 应用程序?
【发布时间】:2010-03-19 18:11:55
【问题描述】:

我是 Cocoa 编程领域的新手,我想为我的应用程序添加 Applescript 支持。 Apple 网站上的示例似乎已过时。

如何向我的 Cocoa 应用程序添加 Applescript 支持?

【问题讨论】:

  • 不清楚这个问题是关于使应用程序可编写脚本还是从应用程序调用脚本。

标签: objective-c cocoa applescript


【解决方案1】:
  1. 如果您想从应用程序发送 AppleScript 并需要沙盒应用程序,则需要创建临时授权

  2. 您需要在 info.plist 中添加这两个键

    <key>NSAppleScriptEnabled</key>
    <true/>
    <key>OSAScriptingDefinition</key>
    <string>MyAppName.sdef</string>
    

...当然,您必须将“MyAppName”更改为您的应用名称

  1. 创建一个 .sdef 文件并将其添加到您的项目中。 现在进一步的课程很大程度上取决于您的应用程序的需要,有:

    1. 类元素(从 AppleScript 创建对象)
    2. 命令元素(覆盖 NSScriptCommand 并执行“类动词”命令)
    3. 枚举元素
    4. 记录类型元素
    5. 值类型元素 (KVC)
    6. 可可元素

    -

    去这里找到详细的描述和许多关于他们实现的细节:https://developer.apple.com/library/content/documentation/Cocoa/Conceptual/ScriptableCocoaApplications/SApps_script_cmds/SAppsScriptCmds.html

  2. 我发现使用 Class 和 KVC Elements 非常复杂,因为我只想执行一个命令,没什么特别的。因此,为了帮助其他人,这里有一个示例,说明如何使用一个参数创建一个新的简单 command。在这个例子中,它会像这样“查找”一个字符串:

    tell application "MyAppName"
        lookup "some string"
    end tell
    
  3. 此命令的 .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>
    
  4. 创建一个 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。我希望这可以帮助某人更快地获得它...

【讨论】:

  • 谢谢。只是补充。当您第一次设置它并在之后进行任何更改时。您将需要重新运行并构建应用程序。不仅仅是建造。同时退出并重新启动 Applescript Editor 以清除其缓存。我通过反复试验艰难地发现了这一点。但是后来当我阅读文档(无论如何都是其中的一部分)时,确认需要这样做:-)
  • 有史以来最好的脚本答案。谢谢。
  • 不应该这样获取直接参数。您可以在您的 NSScriptCommand 子类中简单地使用 self.directParameter
  • 这是一个很好的答案,非常感谢!请注意,如果 AppleScript 感叹缺少处理程序:在我的情况下,我需要将应用程序名称准备到 Sdef 文件中的 Cocoa 类:&lt;cocoa class="MyAppName.MyLookupCommand"/&gt;
  • 这也适用于swift,只需要在类前添加@objc(MyLookupCommand)
【解决方案2】:

现代版本的 Cocoa 可以直接解释脚本定义 (.sdef) 属性列表,因此您需要为基本 AppleScript 支持做的就是根据文档创建 sdef,将其添加到“复制捆绑资源”阶段,然后在 Info.plist 中声明 AppleScript 支持。要访问 NSApp 以外的对象,您需要定义对象说明符,因此每个对象都知道它在脚本世界层次结构中的位置。这使您可以对对象属性进行 kvc 操作,并能够将对象方法用作简单的脚本命令。

【讨论】:

  • “要访问 NSApp 以外的对象,您需要定义对象说明符” - 这是在哪里记录的?能否提供直接链接?
【解决方案3】:

一个简单的例子让你开始,

将脚本(命名对话框)放入文档文件夹,然后您可以从 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){

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-11-02
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多