【问题标题】:Pass a Cocoa NSArray to an Applescript list将 Cocoa NSArray 传递给 Applescript 列表
【发布时间】:2019-03-06 22:11:46
【问题描述】:

我有一个运行 applescript 的应用程序。要求之一是获取在 Objective-C 中创建的数组并将其作为列表传递给 Applescript。

我的代码允许我运行带有变量的applescript,这样我就可以成功传递变量,但我还没有弄清楚数组。

无论如何,我有 NSArray,但我不知道如何让 Applescript 使它可用。我可以将变量传递给 Applescript,但我不知道如何发送数组以便它可用。

如何获得这样的 Obj-C NSArray:

NSMutableArray *myColors;
myColors = [NSMutableArray arrayWithObjects: @"Red", @"Green", @"Blue", @"Yellow", nil];

进入这样的 Applescript 列表:

set colorList to {"Red","Green","Blue"} as list

我试过没有用

set colorList to myColors as list

这就是将变量传递给applescript FYI的方式

#import "Utils.h"

@implementation Utils

+ (NSArray *)arrayFromDescriptor:(NSAppleEventDescriptor *)descriptor {
    // Enumerate the apple descriptors (lists) returned by the applescript and
    // make them into arrays
    NSMutableArray *returnArray = [NSMutableArray array];
    NSInteger counter, count = [descriptor numberOfItems];

    for (counter = 1; counter <= count; counter++) {
        NSAppleEventDescriptor *desc = [descriptor descriptorAtIndex:counter];
        if (nil != [desc descriptorAtIndex:1]) {
            [returnArray addObject:[Utils arrayFromDescriptor:desc]];
        } else {
            NSString *stringValue = [[descriptor descriptorAtIndex:counter] stringValue];
            if (nil != stringValue) {
                [returnArray addObject:stringValue];
            } else {
                [returnArray addObject:@""];
            }
        }
    }
    return returnArray;
}
+ (NSString *)escapeCharacters:(NSString *)string {
    return [string stringByReplacingOccurrencesOfString:@"\"" withString:@"\\\""];
}

+ (NSArray *)runApplescript:(NSString *)source withVariables:(NSDictionary *)variables {
    NSString *input = @"";
    NSArray *variableNames = [variables allKeys];
    // Transform the dictionary of names/values to set sentences of applescript
    for (NSString *variableName in variableNames) {
        NSObject *variableValue = [variables objectForKey:variableName];
        if ([variableValue isKindOfClass:[NSString class]]) {
            input =
                [input stringByAppendingString:[NSString stringWithFormat:@"set %@ to (\"%@\" as text)\n", variableName,
                                                                          [Utils escapeCharacters:variableValue], nil]];
        } else if ([variableValue isKindOfClass:[NSNumber class]]) {
            input = [input stringByAppendingString:[NSString stringWithFormat:@"set %@ to (%@ as integer)\n",
                                                                              variableName, variableValue, nil]];
        } else if ([variableValue isKindOfClass:[NSArray class]]) {
            // Initialize a list
            NSString *entry;
            NSArray *values = (NSArray *)variableValue;
            input = [input stringByAppendingString:[NSString stringWithFormat:@"set %@ to {", variableName]];
            BOOL first = TRUE;
            for (entry in values) {
                if (!first) {
                    input = [input stringByAppendingString:@", "];
                }
                input = [input
                    stringByAppendingString:[NSString stringWithFormat:@"\"%@\"", [Utils escapeCharacters:entry], nil]];

                first = FALSE;
            }
            input = [input stringByAppendingString:@"}\n"];
        }
    }
    NSString *finalScript = [input stringByAppendingString:[NSString stringWithFormat:@"\n\n%@", source]];
    NSLog(@"Final script: %@", finalScript);
    NSAppleScript *script = [[NSAppleScript alloc] initWithSource:finalScript];
    NSDictionary *error;
    NSAppleEventDescriptor *descriptor = [script executeAndReturnError:&error];
    NSLog(@"applescript error: %@", [error description]);
    // Transform the return value of applescript to nested nsarrays
    return [Utils arrayFromDescriptor:descriptor];
}
+ (NSArray *)runApplescriptFromFile:(NSString *)scriptName withVariables:(NSDictionary *)variables {
    NSString *scriptPath = [[NSBundle mainBundle] pathForResource:scriptName ofType:@"applescript"];
    NSString *scriptSource =
        [[NSString alloc] initWithContentsOfFile:scriptPath encoding:NSASCIIStringEncoding error:nil];
    return [Utils runApplescript:scriptSource withVariables:variables];
}
+ (BOOL)stringIsEmptyOrWhite:(NSString *)string {
    string = [string stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceCharacterSet]];
    return [string isEqualToString:@""];
}

@end

然后从我的代码中调用它:

[Utils runApplescript:scriptSource withVariables:variables];

【问题讨论】:

  • 如何将 ObjC 数组传递给 AppleScript?
  • 你正在混合苹果和橙子。如果您要运行,请致电runAppleScript,您不能通过 任何东西;您只需将脚本构造为字符串并运行它。然而,正确的方法是构造一个 NSAppleScript 对象。 (如果我错了,@vadian 纠正我;我已经很久没有这样做了,我已经忘记了很多。)
  • 是要将变量传递给脚本还是要在脚本源中设置变量? finalScript 可以吗,它在脚本编辑器中有效吗?你能举一个variables的值的例子吗?我试过你的代码,数组工作正常。

标签: objective-c macos cocoa applescript


【解决方案1】:

现在,AppleScript 使用 Cocoa-Scripting Bridge。 macOS 10.10 之后,可以在 AppleScript 中使用 Cocoa 函数。

如果你用你的 Objective-C 程序制作 Cocoa 框架,你可以调用自定义的 cocoa 框架。 Objective-C 程序返回 NSArray,然后将该值强制转换为 AppleScript 列表。

https://developer.apple.com/library/archive/releasenotes/ScriptingAutomation/RN-AppleScriptObjC/index.html

我从 Github 上的 Bayes 程序制作了 BayesKit.framework,并从 AppleScript 中调用它。 BayesKit 返回 NSDictionary 并将结果关联到 AppleScript 记录中。

http://piyocast.com/as/archives/4756

【讨论】:

    猜你喜欢
    • 2012-12-06
    • 2012-02-13
    • 1970-01-01
    • 1970-01-01
    • 2015-10-14
    • 2016-04-03
    • 2011-08-02
    • 2014-04-29
    • 1970-01-01
    相关资源
    最近更新 更多