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 (Cocoa-dev@lists.apple.com)

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:
https://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

This email sent to arch...@mail-archive.com

Reply via email to