Reputation: 6959
so I'm working on my little Mac app, and I want control Adium with it. AppleScript is very cool:
tell application "Adium"
go away with message "Zoned in for Maths."
end tell
(If you're wondering what this is supposed to be. In order to actually start studying I need to create application that will change my IM status, of course ... )
I tried it in Script Editor, it worked, and I'm pretty sure that calling AppleScript from Cocoa application is gonna be trivial.
But.
Is AppleScript the only way? I don't mind using AppleScript, but it looks like programming for noobs.
Is there any way to do the same thing as above code does without AppleScript, in plain Objective-C somehow?
Would someone point me to relevant documentation? I tried Google but it was like I don't even know what I'm looking for.
Thanks!
Upvotes: 2
Views: 1071
Reputation: 818
Others have mentioned sending full Applescript or using the Scripting Bridge. A third choice is to use Appscript which is also available for Python and Ruby. It is a little cleaner (IMO) than using the Scripting Bridge in some ways. And definitely easier. Although in other ways Scripting Bridge is better. It also has the advantage of an application called ASTranslate which will translate most Applescript calls into Appscript. Here's the Appscript for your little Applescript example.
ADApplication *adium = [ADApplication applicationWithName: @"Adium"];
ADGoAwayCommand *cmd = [[adium goAway] withMessage: @"Zoned in for Maths."];
id result = [cmd send];
Upvotes: 1
Reputation: 77450
The simplest way would be to use NSAppleScript
NSAppleScript *script = [[NSAppleScript alloc]
initWithSource:@"tell application \"Adium\" to go away with message \"Zoned in for Maths.\""
];
For a more powerful way of accessing scripting, use Scripting Bridge. Scripting Bridge requires at least the 10.5 SDK. You first need to prepare your app.
sdef
and sdp
command line utilities to generating header files for the applications you wish to control (see "Preparing to Code" for details). After that, you can use Objective-C to send scripting commands to the application.
AdiumApplication *adium = [SBApplication applicationWithBundleIdentifier:@"com.adiumX.adiumX"];
for (AdiumAccount* acct in [adium accounts]) {
[acct goAwayWithMessage:(AdiumRichText *)@"Zoned in for Maths."];
}
Status messages are Adium's rich text type (which is NSTextStorage
under the hood), but it's convertable from plain text, so passing an NSString
rather than a true AdiumRichText
should work fine.
There are a few hoops to jump through. For example, you can't create scripting objects in the target application by using its ObjC classes directly; you must use classForScriptingClass:
to get the class, which you can then use to create objects as normal (i.e. alloc
and init
, initWithProperties
&c.).
// 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];
}
Note that other languages (such as Python and Ruby) also have Scripting bindings.
Upvotes: 7
Reputation: 34195
Interprocess communication in Mac OS X is done by something called Apple Events. AppleScript is one way to send and receive Apple Events to other applications.
Therefore, you just need to construct Apple Events directly and send it to the other app, from Objective-C or whatever other language.
Honestly, if you just want to change the status of Adium, it's easiest to use NSAppleScript
and pass what you just wrote, from inside Objective-C.
If you want to do more complicated stuff, Scripting Bridge is the way to go. This mechanism maps Apple Events' object hierarchy to Objective-C's object hierarchy.
If you think that's still a newbie's way, you should directly create Apple Events via NSAppleEventDescriptor
.
Well, some of us old timers think using Objective-C is a sissy's way. If you think so, you should directly deal with C structs called AEDesc
and such. See Apple Events programming guide and the corresponding reference.
However, I think people who use OS X are all noobs. Real people use Linux.
My dad would say people who use GUI are just too spoiled.
The point is, you don't have to care whether it is a newbie's way or not. The important thing is whether you can achieve what you want. In fact, AppleScript is a very powerful, dynamical language, whose power is not well appreciated by many people. Read AppleScript language guide and be surprised.
Upvotes: 10