Querying Class & Command Descs from NSScriptSuiteRegistry

Hi!


I want to get access to the

NSScriptClassDescription & NSScriptCommandDescription objects for a running application via the NSScriptSuiteRegistry object but I'm not having much luck.


I was hoping that all running applications that have a sdef file would be listed when calling the var suiteNames: [String]function, but this doesn't return any suite names for running apps that have sdef files. It returns names like NSCoreSuite, NSTextSuite, ASKDocumentSuite.


I then thought perhaps the suites aren't loaded until the app responds to an Apple Event so I fired off a quick NSScriptObject instance targeting the app I'm wanting to see the suite defs for, but that had no effect on suite names ruturned from NSScriptSuiteRegistry.


Is it even possible to inspect the AppleScript definition for a 3rd party or Apple app with NSScriptSuiteRegistry? I really don't want to have to import an sdef into Core Data and build it myself, if I can simply query the system at run time.

Replies

“Yes. This is exactly what Script Editor does when you run a script.”


Not exactly. SE is just a host for OSA language components. The language itself is responsible for building and sending AEs. In AppleScript’s case, the parser uses lookup tables built from an app’s AETE resource to convert property/element/command/etc names in a script’s source code to the corresponding OSTypes (four-char codes) which are stored in the generated bytecode. On executing that bytecode, the interpreter calls the C AEM APIs to assemble typeObjectSpecifier and typeAppleEvent records and send them to the app process.


Since OSA is built on the Carbon ComponentManager (which is an old and gnarly in-process plugin mechanism), and SE (also being old and gnarly) loads OSA components directly instead of into separate subprocesses as per modern recommendations, then yeah, outgoing AEs and their replies will be sent from and to the SE process itself, which is why Apple grant SE special exemption to standard sandboxing rules. But that’s a separate pain point/discussion, so let’s not get into that here.

>One good thing about Apple’s CS docs if memory serves: it’s the once place where they do talk about one-to-one and one-to-many relationships, which is the key to understanding how an Apple Event Object Model really works.


I'm actually glad I read the higher-level Cocoa docs first. It's actually very easy to understand the design.


> As far as studying other code, the only other AE bridge of worth is Frontier’s, but I don’t think you’ll glean much from that as it’s ancient, ancient C


I was reading an article on AE from 1992 and all the example code was written in Pascal :-O


Thanks for the SourceForge link. I'll only message you if I get really stuck. Plus I've still got to read the AE Programming Guide this weekend and go through your project, so you probably won't hear from me for a while.

This subprocess issue is one I was thinking about recently. I see there are security issues regarding IPC and just haven't had the time to look into it yet. An app has to request temporary entitlements or specify exactly which apps it wan't to communicate with. But I guess those entitlements would extend to subprocesses. If anything it would prevent the main app process from crashing and allow you to save face albeit only slightly if an AE IPC process crashed.

But I guess those entitlements would extend to subprocesses.

That is a complicated question, and one I’d recommend that you avoid trying to deal with. Fortunately that’s not a problem because…

If anything it would prevent the main app process from crashing and allow you to save face albeit only slightly if an AE IPC process crashed.

This is not necessary. If the process you target via Apple events crashes, your Apple event operation will fail with an error. It won’t trigger a crash in your process.

Share and Enjoy

Quinn “The Eskimo!”
Apple Developer Relations, Developer Technical Support, Core OS/Hardware

let myEmail = "eskimo" + "1" + "@apple.com"

Thanks for clearing that up for me. Once I learnt the AEM data structures and had a read through a lot of Inside Macintosh: Interapp Communication, it seems quite easy to follow.


Any idea where the Text Suite's script definition files are located on macOS? I've found ScriptingAddtions, DatabaseEvents etc, but can't seem to find the Text Suite.

I don’t think there is one. There’s a default Standard Suite definition at /System/Library/ScriptingDefinitions/CocoaStandard.sdef, which CS-based apps can XInclude in their own SDEFs (because nothing makes XML parsing more fun than having to deal with XIncludes too; this is why SA ended up using Cocoa’s bulky XML DOM API instead of faster, simpler CF SAX APIs), but AFAIK CocoaScripting’s default Text Suite is always included via cut-n-paste.


Don’t expect too much rigor or polish from CocoaScripting. IIRC it was originally created by a NeXT engineer working blind from internal AppleScript documentation, and later patched up by the Mac Automation team into something that usually mostly works, but it has various legacy bugs and flaws in addition to the inevitable challenge of trying to be a robust, efficient, usable framework for a painfully underspecced AEOM. Fair attempt, but far from complete success.


BTW, the standard Text Suite implementation is famously buggy, e.g. this will disappear your text before your eyes, so don’t run it on anything important:


tell front document of application "TextEdit"

move last word of paragraph 1 to end of paragraph 2

end tell


(It’s also, as I recall, fabulously slow; CS’s one-size-fits-all query-mapping abstraction doesn’t do well representing lots of single characters; quelle surprise. It would’ve made more sense to treat `character` elements as *character ranges*, i.e. substrings, which is what users invariably want anyway.)