- Создание программ для Mac OS X. Часть 3: Apple Script
- Язык, очень похожий на натуральный
- Скриптинг для Mac OS X: начинаем программировать на AppleSсriрt
- Содержание статьи
- Автоматизируй это
- Простой сценарий
- Панель с дополнительными кнопками
- Читаем контент
- Взаимодействие c приложениями
- Запускаем нужный плейлист в iTunes
- Выполнение AppleScript из своего приложения
- Автоматизация в Cocoa-приложении
- Пример sdef-файла
- Заключение
Создание программ для Mac OS X. Часть 3: Apple Script
В этой части я расскажу про еще одно интересное средство разработки приложений для Mac OS X — скриптового языка Apple Script.
Apple Script разрабатывался чтобы применяться конечными пользователями, а не программистами, и позволить им контролировать приложения и документы, с которыми они работают. Например, с помощью Apple Script можно открыть фотографию в редакторе изображений, обрезать до нужного размера, записать ссылку на фото в текстовый файл и т.п.
В отличии от того, как пользователь через GUI взаимодействует с приложением, например впечатывает информацию в текстовые поля приложения для работы с базами данных, AppleScript работает совсем иначе, скрипт использует внутреннюю объектную модель приложения, тем самым внося значения в саму базу данных. Это означает, что во время работы скрипта приложение даже не обязательно показывать. Естественно такая модель работы требует того, чтобы ваше приложение было написано с поддержкой Apple Script.
Каждое приложение, которое понимает Apple Script, публикует поддерживаемые комманды в Apple Event словаре, который используется, чтобы определить допустимые комманды.
Язык, очень похожий на натуральный
в подкасте Радио-Т ведущий bobuk говорил что скрипт, написанный на языке Apple Script читается как обычный английский текст. В принцие он прав, т.к. это и есть одна из основополагающих особеннойстей Apple Script.
Движок Apple Script комбинирует глаголы и существительные, чтобы выполнить действия. Например, чтобы напечатать документ, страницу из документа или опеределенный фрагмент, вместо вызова функций printPage, printDocument, printRange, мы берем глагол print и добавляем нужное существительное:
print page 1
print document 2
print pages 1 thru 5 of document 2
tell application «iTunes»
playpause
end tell
tell application «Microsoft Word» to quit
tell application «QuarkXPress»
tell document 1
tell page 2
tell text box 1
set word 5 to «Apple»
end tell
end tell
end tell
end tell
Использовать иерархичность можно следующим образом:
pixel 7 of row 3 of TIFF image «my bitmap»
set pix to 72
set answer to text returned of (display dialog «Enter in the number of inches» default answer «1»)
display dialog answer & «in = » & (answer * pix) & «px»
при исполнии покажет диалоговое окно с запросом ввода кол-ва дюймов, потом это значение конвертируется в пиксели и результат показывается в следующем окне.
Также скрипт можно сохранить чтобы в дальнейшем использовать как полноценное приложение. Обработчик события запуска должен находиться внутри следующей конструкции:
В принципе, его можно и не писать, тогда при запуске обработка скрипта начнется с первой строки в файле.
Если бросить на файл со скриптом пару других файлов, то при запуске будет использован следующий обработчик:
on open theItems
— что-нибудь делаем с этими самыми theItems
end open
Средстав для написания скриптов лежат в /Applications/AppleScript
В качестве редактора/интерпритатора исаользуется ScriptEditor.app
Чтобы открыть Apple Event словарь надо в меню Script Editor нажать File=> Open Dictionary, откроется окно со списком приложений
выбираем нужное(например iTunes) и клацаем OK. Открылось окно с описанием комманд для нужного нам приложения
А теперь напишем простенькое Cocoa приложение, с помощью которого можно контроллировать iTunes
Открываем XCode, File=>New Project, Cocoa Application => в Project Name пишем iTunes_Controller. Добавляем новый Objective-C class «controller». В файле controller.h пишем
interface controller: NSObject <
>
— (IBAction) nextClick:(id)sender;
— (IBAction) prevClick:(id)sender;
— (IBAction) pauseClick:(id)sender;
— (IBAction) playClick:(id)sender;
— (void) executeAppleScript:(NSString*)sctript;
end
В принципе, в этом коде ничего секретно-военного нету. Просто пишем класс, с помощью которого и будем контролировать iTunes. Функции *Click — это обработчики нажатия по соответствующим кнопочкам на форме. А executeAppleScript:(NSString*)sctript — функция, которая будет исполнять скрипт в параметре script.
А теперь клацаем по MainMenu.nib и попадаем в InterfaceBuilder. Добавляем в окно MainMenu.nib новый NSObject и назначем ему класс controller:
Затем разместим на форме четыре кнопки с надписями «next»,«play»,«pause»,«previous» и соеденим их с соотв. обработчиками из класса controller:
Сохраняем все и возвращаемся в XCode. В файле controller.m пишем следующее:
— (void) executeAppleScript:(NSString*)script <
try <
NSAppleScript *ascript = [[NSAppleScript alloc] initWithSource:script];
[ascript executeAndReturnError:nil];
[ascript release];
>
catch (NSException * e) <
NSLog(@«exception:%@»,e);
>
>
— (void) nextClick:(id)sender <
[self executeAppleScript:@«tell application \»iTunes\» \n next track \n end tell»];
>
— (void) prevClick:(id)sender <
[self executeAppleScript:@«tell application \»iTunes\» \n previous track \n end tell»];
>
— (void) playClick:(id)sender <
[self executeAppleScript:@«tell application \»iTunes\» \n play \n end tell»];
>
— (void) pauseClick:(id)sender <
[self executeAppleScript:@«tell application \»iTunes\» \n pause \n end tell»];
>
В принципе в этом коде ничего сложного тоже нет. Единственная интересная вещь — класс NSAppleScript, с помощью объекта которого и выполняем скрипт. Подробнее про NSAppleScript можно почитать здесь.
В принципе, я думаю, что этого достаточно чтобы получить общее представление о Apple Script и попробавть что-нибудь на нем написать.
Источник
Скриптинг для Mac OS X: начинаем программировать на AppleSсriрt
Содержание статьи
Из этой статьи ты узнаешь, что такое AppleScript, зачем и кому он нужен, как можно автоматизировать чужие приложения и добавлять возможность автоматизации в свои.
Автоматизируй это
Часто встречаются такие задачи, для решения которых делать отдельный проект на компилируемом языке нерационально. Например, когда нужно быстро слепить на коленке код, который должен просто выполнять конкретную работу — без всяких GUI-украшений, обработки всевозможных исключительных ситуаций, оптимизации и прочего. Здесь на помощь и приходят языки сценариев — известные тебе shell, Perl, PHP и так далее. Все они (ну или почти все) доступны и под Mac OS X. Но в этой операционке в дополнение к общепринятым скриптовым языкам есть и специальный язык сценариев, ориентированный именно на Mac OS X и тесно с ней связанный. Это AppleScript.
AppleScript идет вместе с системой начиная с System 7. Выросший из проекта HyperCard (который содержал скриптовый язык HyperTalk, очень похожий на естественный английский), AppleScript первоначально создавался для того, чтобы обеспечить обмен данными между задачами, а также для управления работой сторонних приложений. Сам по себе AppleScript обладает довольно скромной функциональностью: на этом языке даже сценарии для выполнения сравнительно простых задач часто выглядят как обращение к другим приложениям. Впрочем, после существенной перестройки системы при переходе к линейке Mac OS X язык AppleScript стал боле гибким и мощным, а новый фреймворк Cocoa позволил разработчикам встраивать в свои приложения возможность автоматизации с помощью AppleScript’а с минимальными усилиями.
Простой сценарий
Для редактирования и исполнения скриптов мы будем использовать стандартный Script Editor. Найти его можно в папке /Application/AppleScript. Для начала напишем простой «HelloWorld’ный» скрипт.
display alert «Hello World!» # Покажем диалог
say «Hello World» # Вывод в колонки
Объяснять тут, думаю, ничего не нужно, но хочется отметить крайне простой доступ к синтезатору речи из AppleScript c помощью команды say. Вот это и есть настоящее общение с пользователем в стиле Apple :). Конечно же, этот диалог можно легко кастомизировать. Например, добавить нужные кнопки:
Панель с дополнительными кнопками
display alert «Hello World!» buttons <"Hello", "Bye">
set answer to button returned of the result
if answer is «Hello» then
.
else
.
end if
Теперь напишем что-нибудь более полезное. Например, дадим пользователю выбрать файл и прочитаем его содержимое:
# Панель выбора файла
set theFile to (choose file with prompt «Select a file to read:» of type <"TEXT">)
open for access theFile
Читаем контент
set fileContents to (read theFile)
close access theFile
На этих примерах хорошо видна основная идея AppleScript — он очень близок к живому английскому языку. Поэтому читать скрипты легко даже для человека, далекого от кодинга. Каждая командаглагол может быть дополнена существительными-модификаторами и параметрами.
Взаимодействие c приложениями
Для взаимодействия с другими приложениями AppleScript использует механизм сообщений:
tell application «Microsoft Word»
quit
end tell
C помощью команды tell выбираем приложение, которому мы будем отправлять сообщение. В данном случае мы просим MS Word завершиться. В блоке «tell — end tell» может быть отправлено любое количество команд. Сообщения, которые отсылаются приложению, могут быть и более специфичными. Все зависит от того, какие команды реализовали его разработчики. iTunes, например, экспортирует довольно много команд и свойств в среду AppleScript:
Запускаем нужный плейлист в iTunes
tell application «iTunes»
play the playlist named «My Favorite»
end tell
Узнать набор сообщений и типов данных, которые приложение экспортирует в среду AppleScript, можно, посмотрев его терминологию (файл AppName.scriptRerminology в ресурсах приложения). Для этого в Script Editor’е пойдем в меню «File — Open Dictionary — . », и выберем нужное приложение.
Чтобы тебе было проще работать с классами и командами, которые экспортирует приложение, они организованы в разделы. Все приложения, которые поддерживают скриптинг, имеют хотя бы два раздела: один стандартный и один из более специфичных для данного приложения разделов. Стандартный раздел содержит набор стандартных команд, которые поддерживает любое Mac-приложение: open, print, close и quit. Содержание остальных разделов зависит от фантазии разработчиков.
Выполнение AppleScript из своего приложения
Если ты пишешь приложение на Objective-C/Cocoa, то возможно, что некоторые вещи будет удобнее сделать с помощью AppleScript. Для создания и выполнения в Cocoa-приложениях скриптов существует класс NSAppleScript. Вот простой пример его использования — реализация получения у приложения iChat строки статуса пользователя.
NSAppleScript *iChatGetStatusScript = nil;
iChatGetStatusScript = [[NSAppleScript alloc] initWithSource: @»tell application «iChat» to get status message»];
NSString *statusString = [[iChatGetStatusScript executeAndReturnError:&errorDict] stringValue];
Возможно, то же самое можно сделать и другим путем, не используя созданный во время выполнения скрипт, но вряд ли альтернативный код будет выглядеть проще, чем этот. Если скрипты большие, можно хранить их в ресурсах бандла и читать при необходимости.
Автоматизация в Cocoa-приложении
Очень полезно добавлять поддержку скриптинга в свои Сocoaприложения, ведь если в твоем приложении есть интерфейс к AppleScript, то пользователь, написав несколько строчек на AppleScript, сможет кастомизировать его для своих нужд и интегрировать с другими приложениями, которые у него установлены, а затем, например, автоматизировать решение рутинных задач. Чтобы экспортировать типы и команды в среду AppleScript, необходимо их описать в специальных файлах. Есть возможность сделать это в файлах .scriptSuite и .scriptTerminology или в одном файле с расширением .sdef. В обоих случаях файлы имеют формат XML, но с sdef работать проще.
Содержимое файла scriptTermonology отображается в Script Editor’е при просмотре словаря приложения. Этот файл содержит описание экспортируемых в AppleScript объектов.
Открыв scriptSuite-файл в Plist Editor’е, можно видеть, что он содержит следующие основные разделы:
- AppleEventCode — четырехбуквенный код, который идентифицирует приложение для среды AppleScript (код должен быть уникальным в рамках одной системы);
- Name — имя раздела, который содержит экспортируемые команды и классы.
Разбирать внутреннее устройство этих файлов особого смысла нет, так как тебе скорее всего придется иметь дело только с sdef-файлами.
Пример sdef-файла
В sdef’е скриптинг-терминология смешана с подробным описанием команд и типов, которое можно найти в .scriptingSuit-файлах. Реализуем это на практике, создав Cocoa-приложение, поддерживающее AppleScripting. Для этого в новом Cocoa проекте добавим в файл Info.plist флажок Scripting и OSAScriptingDefinition с именем нашего sdefфайла:
.
NSAppleScriptEnabled
Scrtipting.sdef
Добавим к проекту файл Scripting.sdef следующего содержания:
Итак, из AppleScript’а у нас доступно одно свойство — myprop. Осталось написать ObjC-код, который будет обрабатывать чтение данного свойства из скриптов. Для этого нужно создать категорию NSApplication, поскольку именно этот класс мы выбрали в качестве получателя сообщений от скриптов.
#import
@interface NSApplication (Scripting) — (NSString *) myprop;
@end
@implementation NSApplication (Scripting) — (NSString *) myprop
<
return @»This is my property»;
>
Eсли мы теперь из AppleScript обратимся к свойствам нашего приложения, то увидим среди них свое свойство и его значение:
tell application «Scripting»
properties
end tell
Заключение
Конечно, описать здесь все возможности AppleScript и его взаимодействия с Cocoa-приложениями невозможно. Да это и не нужно — для этого есть мануалы. А мы со своей стороны продолжим цикл статей о кодинге под эппловские платформы и расскажем тебе еще много нового и интересного.
Источник