objective-c - 将参数列表或数组从 Obj-C 传递到 Applescript

标签 objective-c macos applescript parameter-passing appstore-sandbox

我正在编写沙盒 Mac OS X (10.10) 应用程序,该应用程序应该启动一些 Applescript。 这是脚本:

on terminal(params)
tell application "Terminal"
do script "who"
repeat with counter_variable_name from 1 to count of params
    set current_character to item counter_variable_name of params
    do script current_character in window 1
end repeat
end tell
end terminal

这是准备调用的代码:

- (NSAppleEventDescriptor *)commandEventDescriptor:(NSString*) command withParams:(NSArray*)inputParams{
NSUInteger c=1;
NSAppleEventDescriptor *parameters = [NSAppleEventDescriptor listDescriptor];
for (NSString* s in inputParams) {
    NSAppleEventDescriptor *parameter = [NSAppleEventDescriptor descriptorWithString:s];
    [parameters insertDescriptor:parameter atIndex:c]; 
    parameter=nil;
    c++;
}

// target
ProcessSerialNumber psn = {0, kCurrentProcess};
NSAppleEventDescriptor *target = [NSAppleEventDescriptor descriptorWithDescriptorType:typeProcessSerialNumber bytes:&psn length:sizeof(ProcessSerialNumber)];

// function
NSAppleEventDescriptor *function = [NSAppleEventDescriptor descriptorWithString:command];

// event
NSAppleEventDescriptor *event = [NSAppleEventDescriptor appleEventWithEventClass:kASAppleScriptSuite eventID:kASSubroutineEvent targetDescriptor:target returnID:kAutoGenerateReturnID transactionID:kAnyTransactionID];
[event setParamDescriptor:function forKeyword:keyASSubroutineName];
[event setParamDescriptor:parameters forKeyword:keyDirectObject];
parameters=nil;
function=nil;
return event;}

这是调用:

NSUserAppleScriptTask *automationScriptTask = [self automationScriptTask];
if (automationScriptTask) {
    NSAppleEventDescriptor *event = [self commandEventDescriptor:@"terminal" withParams:@[@"date",@"time"]];
    [automationScriptTask executeWithAppleEvent:event completionHandler:^(NSAppleEventDescriptor *resultEventDescriptor, NSError *error) {
        if (! resultEventDescriptor) {
            NSLog(@"%s AppleScript task error = %@", __PRETTY_FUNCTION__, error);
        }
        else {
            
        }
    }];
}

我的期望是在终端中获得类似的内容:

macbook:~ xxx$ who

macbook:~ xxx$ date

macbook:~ xxx$ time

相反,我有:

macbook :xxx$ who

macbook :xxx$ d

-bash: d: command not found

macbook :xxx$ a

-bash: a: command not found

macbook :xxx$ t

-bash: t: command not found

macbook :xxx$ e

-bash: e: command not found

简单地说:我想传递给 Applescript 两个值(“日期”和“时间”)的数组,但脚本只接收一个(第一个)值。对 params 进行迭代仅给出“d”、“a”、“t”、“e”。

那么我哪里出错了?

最佳答案

我想我已经找到答案了。不完全确定这是否是正确和规范的答案,但它似乎是在正确的方向上。无论如何,我对问题的理解是上述脚本仅接受一个参数。我提供了两个论点。因此,脚本礼貌地忽略了第二个参数。 我的解决方案是将两个参数打包到一个描述符中,然后将其作为单个参数提供。更具体 - 这是相关代码:

- (NSAppleEventDescriptor *)commandEventDescriptor:(NSString*) command withParams:(NSArray*)inputParams{
NSUInteger c=1;
NSAppleEventDescriptor *parameters = [NSAppleEventDescriptor listDescriptor];
for (NSString* s in inputParams) {
    NSAppleEventDescriptor *parameter = [NSAppleEventDescriptor descriptorWithString:s];
    //indexing starts from 1, NOT 0
    [parameters insertDescriptor:parameter atIndex:c];
    parameter=nil;
    c++;
}
// parameter

// target
ProcessSerialNumber psn = {0, kCurrentProcess};
NSAppleEventDescriptor *target = [NSAppleEventDescriptor descriptorWithDescriptorType:typeProcessSerialNumber bytes:&psn length:sizeof(ProcessSerialNumber)];

// function
NSAppleEventDescriptor *function = [NSAppleEventDescriptor descriptorWithString:command];

// event
NSAppleEventDescriptor *event = [NSAppleEventDescriptor appleEventWithEventClass:kASAppleScriptSuite eventID:kASSubroutineEvent targetDescriptor:target returnID:kAutoGenerateReturnID transactionID:kAnyTransactionID];
[event setParamDescriptor:function forKeyword:keyASSubroutineName];

//packing the pair of arguments into one Event Descriptor
NSAppleEventDescriptor* l0=[NSAppleEventDescriptor listDescriptor];
[l0 insertDescriptor:parameters atIndex:1];

[event setParamDescriptor:l0 forKeyword:keyDirectObject];
parameters=nil;
function=nil;
return event;}

现在脚本的行为符合预期 - 打开终端窗口,运行命令“who”,然后运行命令“date”,然后运行命令“time”。

关于objective-c - 将参数列表或数组从 Obj-C 传递到 Applescript,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34518951/

相关文章:

python - 使用 nix 正确设置全局 python 环境

xcode - 如何在 Xcode 中为自定义 Automator Action 项目连接按钮的发送操作

applescript - 使用 Applescript/Automator 检查事件的互联网连接

applescript - 如何保持 applescript 运行并重定向 url?

ios - 尝试实现相机功能时,xcode 向不兼容类型警告参数抛出 "DetailViewController *"

macos - OS X 如何生成崩溃报告?

c++ - 在同一项目中编译 C++ 和 ObjC 文件

c++ - Xcode 6 : Create pure C++ OpenGL application bundle (. 应用程序)不使用 "Cocoa Application"模板

objective-c - 动画后旋转

ios - UILocalNotification 没有在正确的时间触发