Скриптовость (AppleScript) в приложении Mac Carbon
Я пытаюсь добавить поддержку AppleScripting в свое приложение, не основанное на Какао.
Я работаю низкоуровневые функции, такие как AEGetParamDesc, обрабатывая form
/ want
/ seld
параметры сам.
Мой словарь предлагает класс, назовем его "Имидж". У него есть свойство "имя".
Я получил работающий код Applescript, такой как:
get Images
get name of every Image
get count Images
get every Image
get first Image
get Image 1
Так что, в принципе, доступ к объектам и их свойствам работает.
Тем не менее, когда я попробовал эти похожие формы доступа, все они терпят неудачу:
get Images whose name = "foo"
а также
repeat with img in Images
end repeat
В первом случае, похоже, мне придется справиться с test
форма.
Во втором случае оператор подсчета (cnte
) не запрашивает объект класса напрямую, а вместо этого использует cobj
оператор, описывающий индексный объект.
Все это заставляет меня задуматься, как далеко это зайдет. Должен ли я реализовать каждый возможный синтаксис и оператор Applescript индивидуально в моем коде? Я бы предположил, что оператор "чей" будет просто объединять запросы для "каждого изображения" и "имени изображения х" так, как я могу по отдельности написать их в Applescript, вместо использования различных формул AppleEvent для каждого из них.
То же самое для whose <boolean-test>
, Почему AppleScript просто не выполняет тест на равенство name = "foo"
само по себе, так как это текстовое сравнение, которое вообще не должно включать код моего приложения?
Я что-то упускаю? Могу ли я переслать их в функции AE, о которых я еще не знаю, или я должен сам обрабатывать все возможные команды сравнения и управления потоком?
3 ответа
Томас Темпельманн (слава Find Any File?), Если вы действительно не можете переписать приложение в Какао, вот статья, которую я написал много лет назад, с некоторыми подробностями о кодировании (в C) для сценариев до Какао, включая обработку formWhose, о котором вы спрашивали выше.
http://www.mactech.com/articles/develop/issue_28/reuter.html
Статья была опубликована Apple в ее журнале Develop и включала исходный код, который я написал для примера приложения под названием "Sketch". Это было за годы до того, как Apple выпустила собственный образец проекта, также названный "Sketch". У меня все еще есть исходный код, если он поможет вам.
Удачи!
Объектная модель событий Apple была разработана для IPC с высокой задержкой в операционной системе (система 7), которая могла выполнять до 60 переключений контекста в секунду. Сложные запросы и процедуры, которые могут работать с несколькими объектами, позволяют выполнять больше работы, используя меньше межпроцессных сообщений. Кроме того, он спроектирован как сравнительно толстая абстракция View-Controller с акцентом на UI/UX, представляя идеализированное представление данных пользователя в виде реляционного графа, независимо от того, как на самом деле хранятся базовые данные, насколько сложными или сложными для понимания. реализовать код VC для сопоставления от одного к другому может быть. AEOM имеет гораздо больше общего с реляционными базами данных, чем что-либо в мире ООП, в то время как самой близкой аналогией Apple Event IPC будет отправка XQueries через XML-RPC. Для фона см.:
http://www.cs.utexas.edu/~wcook/Drafts/2006/ashopl.pdf
В настоящее время, разумеется, OS X может выполнять тысячи переключений процессов в секунду, не теряя при этом пота, поэтому меньше необходимости реализовывать сложный AE View-Controller просто для получения приемлемой производительности. TBH, я бы посоветовал вам сэкономить свое время и внедрить простейший RPC, который работает просто, надежно и быстро. Ограничьте обработчики, изменяющие состояние, работой с одним объектом для каждого сообщения (поскольку выполнение операций Set на массивах - это ад, чтобы получить право), реализуйте простейшие формы запросов, необходимые для обнаружения объектов, и возвращайте спецификаторы by-ID, которые в основном действуют как безопасные указатели на ранее идентифицированные объекты, так что пользователи могут быстро манипулировать ими с помощью дальнейших команд без затрат на многократные обходы сложных полных запросов.
Да, и если у вас нет особой причины использовать C, я бы рекомендовал использовать только NSAppleEventDescriptor и NSAppleEventManager. API Apple Event Manager C является древним, корявым и устаревшим с 10.6, поэтому не рекомендуется для новых разработок. Вы могли бы (повторюсь, возможно) даже найти способ использования некоторых классов сценариев Cocoa для выполнения небольшой работы со спецификаторами объекта, хотя CS сам по себе довольно ужасен и тесно связан с ApplicationKit, поэтому не тратьте время на беспорядок с этим, если это действительно не помогает (CS похоронил лучшие проекты раньше).
Другое дело, конечно, в том, что вся экосистема Mac Automation находится в полностью умирающем состоянии и вряд ли станет лучше под текущим управлением, так что цена-против-преимущества разработки полного, сложного AEOM с нуля просто больше нет. Если "просто, быстро, безопасно и глупо" достаточно хорошо для тех пользователей, которых вы надеетесь привлечь, просто сделайте это.
Пример кода Apple для Sketch является хорошим примером использования API сценариев Cocoa.
Пример кода не выполняет какой-либо специальной обработки для "повтор" и "чей", но он может запускать сценарии AppleScripts с использованием этих терминов.
Это говорит о том, что сценарии Какао, т.е. в основном классы и протоколы в NSScriptObjectSpecifiers.h
, заботится о сложной обработке, которую предоставляет старый Carbon API.
Поэтому, основываясь на ответе @foo, представляется разумным попытаться создать прокси-классы на основе NSObject(NSScriptObjectSpecifiers)
, осуществляя objectSpecifier
метод, а также получить / установить методы доступа для любых свойств, а затем использовать возможность ссылаться на эти классы в .sdef
файл. Даже без Objective C такие классы могут быть созданы с использованием функций времени выполнения ObjC, таких как objc_registerClassPair
,