AppleScript это круто.Могу ли я сделать то же самое в обычном Objective-C? - PullRequest
2 голосов
/ 11 декабря 2010

, поэтому я работаю над своим маленьким приложением для Mac и хочу управлять им с помощью Adium.AppleScript очень крутой:

tell application "Adium"
    go away with message "Zoned in for Maths."
end tell

(Если вам интересно, что это должно быть. Чтобы начать обучение, мне нужно создать приложение, которое, конечно, изменит мой статус чата....)

Я попробовал это в Script Editor, это сработало, и я уверен, что вызов AppleScript из приложения Cocoa будет тривиальным.

Но.

Является ли AppleScript единственным способом?Я не против использования AppleScript, но это похоже на программирование для нубов.

Есть ли способ сделать то же самое, что и вышеупомянутый код, без AppleScript, как-то в простом Objective-C?

Кто-нибудь укажет мне на соответствующую документацию?Я пробовал Google, но я даже не знал, что ищу.

Спасибо!

Ответы [ 3 ]

10 голосов
/ 11 декабря 2010

Межпроцессное взаимодействие в Mac OS X осуществляется с помощью программы Apple Events. AppleScript - это один из способов отправки и получения событий Apple в другие приложения.

Следовательно, вам просто нужно создать Apple Events напрямую и отправить его в другое приложение, из Objective-C или любого другого языка.

Честно говоря, если вы просто хотите изменить статус Adium, проще всего использовать NSAppleScript и передавать то, что вы только что написали, из Objective-C.

Если вы хотите делать более сложные вещи, Scripting Bridge - это путь. Этот механизм отображает иерархию объектов Apple Events в иерархию объектов Objective-C.

Если вы думаете, что это все еще новичок, вам следует напрямую создать Apple Events через NSAppleEventDescriptor.

Ну, некоторые из нас, старожилов, думают, что использование Objective-C - это путь сестренки. Если вы так думаете, вам следует напрямую иметь дело со структурами C, называемыми AEDesc и такими. См. Руководство по программированию Apple Events и соответствующую ссылку .

Тем не менее, я думаю, что люди, которые используют OS X, все нубы. Реальные люди используют Linux.

Мой папа сказал бы, что люди, которые используют GUI, просто слишком избалованы.

Суть в том, что вам не нужно заботиться о том, что это за новичок или нет. Важно то, можете ли вы достичь того, чего хотите. На самом деле AppleScript - это очень мощный, динамичный язык, мощность которого не очень хорошо ценится многими людьми. Прочитайте Руководство по языку AppleScript и удивитесь.

6 голосов
/ 11 декабря 2010

Самый простой способ - использовать NSAppleScript

NSAppleScript *script = [[NSAppleScript alloc] 
    initWithSource:@"tell application \"Adium\" to go away with message \"Zoned in for Maths.\""
];

. Для более мощного доступа к сценариям используйте Scripting Bridge .Для скриптового моста требуется как минимум 10.5 SDK.Сначала вам нужно подготовить ваше приложение.

  1. Используйте утилиты командной строки sdef и sdp для создания заголовочных файлов для приложений, которыми вы хотите управлять (см. « Подготовка к коду » для получения подробной информации).
  2. Добавьте сгенерированный заголовок в ваш проект.
  3. Добавьте каркас ScriptingBridge в ваш проект.После этого вы можете использовать вызовы Objective C для управления другим приложением.

После этого вы можете использовать Objective C для отправки команд сценариев в приложение.

AdiumApplication *adium = [SBApplication applicationWithBundleIdentifier:@"com.adiumX.adiumX"];
for (AdiumAccount* acct in [adium accounts]) {
    [acct goAwayWithMessage:(AdiumRichText *)@"Zoned in for Maths."];
}

Сообщения о состоянии имеют формат расширенного текста Adium (который NSTextStorage под капотом), но его можно конвертировать из обычного текста, поэтому передача NSString вместо истинного AdiumRichText должна работать нормально.

Тамнесколько обручей, чтобы прыгать.Например, вы не можете создавать объекты сценариев в целевом приложении, напрямую используя его классы ObjC;Вы должны использовать classForScriptingClass:, чтобы получить класс, который затем можно использовать для создания объектов в обычном режиме (т. е. alloc и init, initWithProperties и т. д.).

// creating an AdiumContactGroup
NSDictionary *props = [NSDictionary 
    dictionaryWithObjectsAndKeys:
        @"mathies",@"name",
        nil
];
AdiumContactGroup *mathies= [[[[adium classForScriptingClass:@"contact group"] alloc] 
                              initWithProperties:props]
                             autorelease];
if (mathies) {
    [[adium contactGroups] addObject:mathies];
}

Обратите внимание, что другие языки (такие как Python и Ruby) также имеют привязки сценариев.

1 голос
/ 13 декабря 2010

Другие упоминали, что отправили полный Applescript или использовали Scripting Bridge. Третий вариант - использовать Appscript , который также доступен для Python и Ruby. Это немного чище (IMO), чем использование скриптового моста в некоторых отношениях. И определенно проще. Хотя в других отношениях Scripting Bridge лучше. Он также имеет преимущество приложения под названием ASTranslate, которое будет переводить большинство вызовов Applescript в Appscript. Вот пример приложения для вашего маленького примера Applescript.

ADApplication *adium = [ADApplication applicationWithName: @"Adium"];
ADGoAwayCommand *cmd = [[adium goAway] withMessage: @"Zoned in for Maths."];
id result = [cmd send];
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...