Передача списка или массива аргументов из Obj-C в Applescript

Я пишу изолированное приложение для 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$ кто

macbook: ~ xxx$ дата

макбук: ~ xxx$ раз

Вместо этого у меня есть:

макбук :xxx$ кто

макбук :xxx$ д

-bash:d:команда не найдена

макбук :xxx$ а

-bash: а: команда не найдена

макбук :xxx$ т

-bash: t: команда не найдена

макбук :xxx$ e

-bash: e: команда не найдена

Проще говоря: я хочу передать в Applescript массив из двух значений (дата и время), но скрипт получает только одно (первое) значение. Итерация по params дает мне только "d", "a", "t", "e".

Так где я ошибся?


person BorisV    schedule 29.12.2015    source источник
comment
Ожидание того, что неработающие команды будут вести себя определенным образом, скорее всего, приведет к неожиданным результатам... ›› 123 недопустимая команда, так что на этом все. если это не то, что вы ожидаете, начните с того, что попробуете что-то действительно стоящее.   -  person l'L'l    schedule 30.12.2015
comment
Я привел пример с действительной командой   -  person BorisV    schedule 30.12.2015
comment
Для изолированного приложения рекомендуемым способом является NSAppleScriptTask доступ к сценариям, связанным с приложением, в ~/Library/Application Scripts или AppleScriptObjC с классом моста ObjC.   -  person vadian    schedule 30.12.2015
comment
извините, но это уведомление правильное и бесполезное   -  person BorisV    schedule 30.12.2015


Ответы (1)


Думаю, я нашел ответ. Не совсем уверен, что это правильный и канонический ответ, но, похоже, он в правильном направлении. Во всяком случае, я понимаю проблему так, что вышеупомянутый скрипт принимает только один аргумент. Я предоставил два аргумента. Таким образом, сценарий вежливо проигнорировал второй аргумент. Мое решение состояло в том, чтобы упаковать оба аргумента в один дескриптор, а затем использовать его как один аргумент. Если быть более конкретным - вот соответствующий код:

- (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;}

Теперь скрипт ведет себя как положено - открывает окно терминала, запускает команду "кто", затем команду "дата", затем команду "время".

person BorisV    schedule 30.12.2015