Техническое примечание TN2084

Используя сценарии AppleScript в приложениях какао

Даже при том, что Ваше приложение записано в Objective C с помощью Какао, можно использовать сценарии AppleScript для выполнения определенных операций. Это Техническое примечание объясняет, как интегрировать и выполнить AppleScripts из Вашего приложения Какао. Это обсуждает, как эффективно использовать класс NSAppleScript и использование NSAppleEventDescriptor для отправки данных в получатель.

Сводка
Создание NSAppleScript
Используя NSAppleScript со встроенной строкой
Используя NSAppleScript со сценарием в пакете приложения
Пример кода
Онлайн-документация
История версии документа

Сводка

NSAppleScript является большим инструментом для межсвязи приложений. Это - удобный способ передать параметры сценарию AppleScript, работающему в Вашем приложении. Это Техническое примечание показывает, как использовать NSAppleScript для загрузки, скомпилируйте и выполните сценарии и NSAppleEventDescriptor для вызова обработчика в загруженном сценарии.

Это Техническое примечание объясняет, как сделать следующее:

Создание NSAppleScript

При создании экземпляра объекта NSAppleScript можно использовать URL для указания сценария, который может быть или в тексте или в скомпилированной форме:

NSAppleScript* appleScript = [[NSAppleScript alloc] initWithContentsOfURL:url error:&errors];

или можно предоставить сценарий как строку при помощи:

NSAppleScript* appleScript = [[NSAppleScript alloc] initWithSource: (NSString *)source];

Если ошибка происходит при компиляции или выполнении сценария, метода [NSAppleScript executeAndReturnError] возвращает словарь, содержащий информацию об ошибке.

Используя NSAppleScript со встроенной строкой

Перечисление 1 показывает, как использовать NSAppleScript для выполнения сложного сценария, встроенного как экземпляр NSString. Если сценарий успешен, код извлекает информацию из возвращенного экземпляра NSAppleEventDescriptor. Выполняемый сценарий устанавливает Ваше приложение как «Элемент Входа в систему» к Установкам системы «Учетных записей».

Перечисление 1  Используя NSAppleScript со встроенной строкой.

- (IBAction)addLoginItem:(id)sender
{
    NSDictionary* errorDict;
    NSAppleEventDescriptor* returnDescriptor = NULL;

    NSAppleScript* scriptObject = [[NSAppleScript alloc] initWithSource:
                @"\
                set app_path to path to me\n\
                tell application \"System Events\"\n\
                if \"AddLoginItem\" is not in (name of every login item) then\n\
                make login item at end with properties {hidden:false, path:app_path}\n\
                end if\n\
                end tell"];

    returnDescriptor = [scriptObject executeAndReturnError: &errorDict];
    [scriptObject release];

    if (returnDescriptor != NULL)
    {
        // successful execution
        if (kAENullEvent != [returnDescriptor descriptorType])
        {
            // script returned an AppleScript result
            if (cAEList == [returnDescriptor descriptorType])
            {
                 // result is a list of other descriptors
            }
            else
            {
                // coerce the result to the appropriate ObjC type
            }
        } 
    }
    else
    {
        // no script result, handle error here
    }
}

Используя NSAppleScript со сценарием в пакете приложения

Следующий код в Перечислении 2 показывает, как Ваше приложение может загрузить сценарий AppleScript из своей папки ресурсов и отправить текстовое сообщение в Средство поиска путем отображения его в диалоговом окне (сценарий описан ниже в Перечислении 3). Это использует серию NSAppleEventDescriptors, чтобы создать параметры сценария, определить имя метода, это вызывают и наконец создать AppleEvent для передачи к Средству поиска.

Перечисление 2  Используя NSAppleScript со сценарием в пакете приложения.

- (IBAction)sendFinderEvent:(id)sender
{
    // load the script from a resource by fetching its URL from within our bundle
    NSString* path = [[NSBundle mainBundle] pathForResource:@"SendFinderMessage" ofType:@"scpt"];
    if (path != nil)
    {
        NSURL* url = [NSURL fileURLWithPath:path];
        if (url != nil)
        {
            NSDictionary* errors = [NSDictionary dictionary];
            NSAppleScript* appleScript =
                    [[NSAppleScript alloc] initWithContentsOfURL:url error:&errors];
            if (appleScript != nil)
            {
                // create the first parameter
                NSAppleEventDescriptor* firstParameter =
                        [NSAppleEventDescriptor descriptorWithString:@"Message from my app."];

                // create and populate the list of parameters (in our case just one)
                NSAppleEventDescriptor* parameters = [NSAppleEventDescriptor listDescriptor];
                [parameters insertDescriptor:firstParameter atIndex:1];

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

                // create an NSAppleEventDescriptor with the script's method name to call,
                // this is used for the script statement: "on show_message(user_message)"
                // Note that the routine name must be in lower case.
                NSAppleEventDescriptor* handler =
                        [NSAppleEventDescriptor descriptorWithString:
                        [@"show_message" lowercaseString]];

                // create the event for an AppleScript subroutine,
                // set the method name and the list of parameters
                NSAppleEventDescriptor* event =
                        [NSAppleEventDescriptor appleEventWithEventClass:kASAppleScriptSuite
                                eventID:kASSubroutineEvent
                                targetDescriptor:target
                                returnID:kAutoGenerateReturnID
                transactionID:kAnyTransactionID];
                [event setParamDescriptor:handler forKeyword:keyASSubroutineName];
                [event setParamDescriptor:parameters forKeyword:keyDirectObject];

                // call the event in AppleScript
                if (![appleScript executeAppleEvent:event error:&errors]); 
                {
                    // report any errors from 'errors'
                }

                [appleScript release];
            }
            else
            {
                // report any errors from 'errors'
            }
        }
    }
}

Перечисление 3  содержание SendFinderMessage.scpt

on show_message(user_message)     tell application "Finder"         display dialog user_message     end tell end show_message

Интеграция скомпилированных сценариев в проект XCode

Так как код в Перечислении 2 загружает сценарий из папки Resources Вашего приложения, необходимо обеспечить этот сценарий в проекте XCode как «скомпилированный сценарий».

Добавление Вашего сценария к Вашему проекту XCode может быть сделано два пути:

1. Скомпилируйте сценарий сами

При создании и редактировании сценария с помощью Редактора сценариев можно сохранить его в двух форматах: текст или сценарий. Формат «сценария» означает «скомпилированный сценарий». Если Вы принимаете решение сохранить его, поскольку скомпилированный сценарий тогда делает следующее с XCode:

  • Перетащите скомпилированный сценарий (в нашем случае «SendFinderMessage.scpt») к Вашему проекту XCode.

  • Включайте файл сценария в «фазу сборки» Ресурсов Пакета Копии.

2. Имейте компиляцию XCode сценарий

Если Вы принимаете решение хранить свой файл сценария как «текстовый» файл, то Вам нужен XCode для компиляции сценария для Вас.

  • Перетащите текстовый файл сценария (в нашем случае «SendFinderMessage.applescript») к Вашему проекту XCode.

  • Создайте новую Фазу Сборки Сценария Выполнения и добавьте следующий (см. пример на рисунке 1):

    osacompile -d -o SendFinderMessage.scpt SendFinderMessage.applescript

  • Создайте новую Фазу Сборки Файлов Копии и сконфигурируйте ее для копирования «SendFinderMessage.scpt» в папку Resources.

Рисунок 1  выполненная фаза сборки сценария

Пример кода

Если Вы хотите исследовать более обширный пример использования сценариев AppleScript в Вашем приложении Какао с помощью методов, описанных в этом Техническом примечании, обратитесь к проекту примера кода AttachAScript.

Онлайн-документация



История версии документа


ДатаПримечания
19.09.2006

Новый документ, объясняющий, как работать со сценариями AppleScript в Вашем приложении Какао.