Re: NSAppleEventDescriptor docs [was: Re: [Swift] best way to support 'keyword' args,...]
Re: NSAppleEventDescriptor docs [was: Re: [Swift] best way to support 'keyword' args,...]
- Subject: Re: NSAppleEventDescriptor docs [was: Re: [Swift] best way to support 'keyword' args,...]
- From: has <email@hidden>
- Date: Tue, 16 Jun 2015 18:42:55 +0100
Dave wrote:
>> Thanks to Apple actioning Radar tickets 19169736
<http://openradar.appspot.com/19169736>, 19169791
<http://openradar.appspot.com/19169791>, and 18944184
<http://openradar.appspot.com/18944184>, there are now modern, fully
supported NSAppleEventDescriptor APIs arriving in 10.11 that will allow
third-party code to do all this stuff without having to go through
ancient legacy or deprecated Carbon APIs any more.
>
> I’m was about to add AppleScript Handling to my App and I’ll need to
do a lot of NSAppleEventDescriptor fishing, is there any advance
documentation relating to this? I’m an Apple Developer and under NDA.
First things first, be aware that Apple event IPC makes *infinitely more
sense* once you realize it ISN'T OOP, but remote procedure calls with
simple first-class relational query values as arguments. Your app's
"scripting interface" presents an idealized view onto its user data as a
relational object graph, against which those queries are then evaluated.
[1] Go read Dr William Cook's HOPL paper for excellent background on why
and how it was designed that way [2]:
http://www.cs.utexas.edu/~wcook/Drafts/2006/ashopl.pdf
The usual way to add AE handling to a Cocoa app is to use the Cocoa
Scripting framework. It has flaws, but unless you've a specific reason
not to use it then it's probably the least painful option currently
available. (If I ever get a spare year with nothing better to do I might
write a replacement, but already I've enough mad projects on the go to
keep me busy for the foreseeable.)
Matt Neuburg's written some useful stuff on CS in the past, and there's
docs on Apple's own site as well, including the Scripting Interface
Guidelines which you should track down and read.
While I don't use CS myself, I understand that the way Cocoa Scripting
handles events and queries is kind of poor: each incoming AE is
dispatched to a corresponding 'Command' class, one for each kind of
event; and it's all a single-dispatch, nominal-typing, traditionalist OO
flavored mindset, where queries tend to get unpacked into arrays of
objects representing individual model objects which then frequently a
pig to wrangle efficiently and correctly, e.g. try running this and see
how many off-by-N errors you can identify:
tell application "TextEdit"
make new document with properties {text:"one two three four
five six sovon eight nine ton"}
set (every word where it contains "e") of document 1 to "?"
end tell
Whereas Apple events really need a multimethod-style approach to
dispatching that uses structural-typing-like pattern matching to route
incoming events to as many different 'handler' classes as you need to
represent all the different verb(noun,noun,noun,...) combinations your
app supports, and lets you decide exactly how you want to resolve
queries and perform operations yourself. e.g. `move document 1 to end of
documents` is a totally different operation to `move word 1 to end of
paragraph 1`, so why would you want it dispatching both requests to the
same NSScriptMoveCommand class? (And let's not even get into the sheer
awfulness of its default Text Suite implementation.)
Like I say, AEs are not OOP, and probably 80% of programmers' pain and
hate comes from wrongly trying to treat them as such (the other 20%
being due to a formal spec that's so hand-wavy and open-ended it's very
hard to figure out how you _should_ do it). OTOH, unless you're willing
(and crazy enough) to design and build your own AE handling framework
from scratch, I recommend you just slum it with CS. Oh, and stick to
AppleScript for _all_ your testing as that is the benchmark and the only
currently supported AE bridge that actually works right[3].
As to wrangling NSAppleEventDescriptor directly (assuming you're either
not using CS, or that CS is unable to pack and unpack them automatically
for you), the docs on developer.apple.com haven't been updated yet, but
the new methods all look to be based on my submitted patches which are
taken from here, so just read the comments on those if they're not
already self-explanatory:
https://bitbucket.org/hhas/appleeventbridge/src
NSAppleEventDescriptor+AEDescExtensions.h
NSAppleEventDescriptor+AEDescMoreExtensions.h
The only difference I've noticed thus far is the -send... event has a
slightly different signature and a bug in the timeout argument, which
I'll radar later [4].
If you're going to start packing and unpacking complex more complex
descriptors (e.g. lists, records) yourself, you may find it useful to
pinch code from my AEMCodecs class too.
If you want to talk about stuff off-list then you're welcome to email me
directly. Matt Neuburg and Shane Stanley are also well worth tracking
down and picking their brains for guru treats, and both periodically
appear on this list too.
HTH
has
[1] Pin this on your wall as a reminder every day: grasping this
unfamiliar but simple truth turns even the AppleScript-loathing
developer into one that still loathes the AppleScript _language_ but
really starts to understand and appreciate the philosophy and
interaction model of the IPC system that actually powers all the cool
desktop automation stuff.
[2] Apple's own public docs *never* tell you this stuff, BTW, which is
why OO programmers get so incredibly frustrated with it. They naturally
assume it's OOP-based messaging because the AS syntax looks like OO, but
that mis-assumption only holds up to the point where it acts in
profoundly not-OO ways; beyond which those poor programmers pull their
hair out as they're unable to reconcile their [incorrect] mental model
of it operates with what it's _actually_ doing right in front of them.
[3] OS X's Scripting Bridge and JavaScript for Automation may seem
tempting to developers, but both have numerous significant design flaws,
feature omissions, confusing obfuscations, and simply don't work right.
(Plus their documentation and their official and community support are
hopeless too.) And it's going to be a few months till my new Swift-AE
bridge is fully working and tested; and even then I'd still tell you to
test against AS as standard.
[4] In converting timeout numbers from seconds (NSTimeInterval) to ticks
(long), it fails to account for kAEDefaultTimeout and kNoTimeOut flags,
causing those flags to behave incorrectly. I just need to finish
updating my own implementation (which still used ticks for just this
reason) and then I'll send it as a patch.
_______________________________________________
Cocoa-dev mailing list (email@hidden)
Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com
Help/Unsubscribe/Update your Subscription:
This email sent to email@hidden