Scripting addition for user defaults?

Is there a way to get / set user defaults of a particular app using plain Applescript, without invoking the “defaults” command? Or, alternatively, is there a parser for the results from the “defaults” command?

I am contemplating whether I should try to add commands to my scriptable app or could rather rely on some more generic solution.

Is this a hint to build this feature in AppleScript Toolbox? :wink:

To answer you question: If the preferences only regards to tour application you should create a preference class in your application which contains writeable properties. If you’re looking for an way to change preferences in user, system, host and application domains you should create an (faceless) application, script library or osax for it.

Well, I’ve already made a GUI for that (, and I could make that scriptable, though having a scripting addiiton would be cleaner.
But then, I’ve already spent much more time on adding scripting to my app and do not want to burden me with even more work. That’s why I asked if there’s already something available.

On a related note, is there an addition for dealing with JSON content?

Even if huge parts of the AppleEvent manager and OSA are undeprecated and out of legacy since January this year, which is great news, osaxen remains it’s flaws. Osaxen cannot be turned on and of individually only all of them or none available, which I think is still a huge drawback. Since Mavericks AppleScript engineers addressed somewhat of the name space pollution but still not all of it.

So cleaner is not something everyone would agree with here, also scriptable applications are way easier to create than creating an osax since you’re working on AppleEvent level which is C and for some people a pain. Since the task of the application itself is already managing user defaults I would say making the application scriptable is in this case the “cleaner” way to go.

There is IIRC an faceless background application that is scriptable to do JSON tasks.

FWIW, most of the development in AS over the past few versions has been focused on providing another alternative to scripting additions. They really are out of favor.

I agree that turning my GUI app into a faceless bg app would be the easiest, now that I have some experience adding scripting to an app.

I just wonder how to best control how long the bg app should run? It won’t appear in the menu bar nor anywhere else, so the user won’t be able to quit it. Instead, the only client of the bg app will be the script. But how does an app tell when its script is finished?

The only way I can come up with is to just let the app quit itself after being not call by the script for a few seconds. But that will also purge any semi-persistent information such as IDs. So, if the script would fetch some data, remember the data’s IDs, pause for a while (e.g. ask the user via a dialog) and then try to access the data by id, that may fail if I use temporary IDs in my app.

For instance, array elements have no inherent IDs, so I cannot make them persistent across re-runs of my helper app. And using just their index causes the issues I had already explained in a previous post here.

Any ideas how other such scripting helper apps solve that?

You need to set a reasonable timeout. Have a look at System Events’s quit delay property, which gives the scripter some control.

Huh. SD 5 does not find a “quit” nor “quit delay” in Scripting Additions. Oh, System Events is not a Scripting Addition?! It’s not listed in the list of scriptable apps, either. Weird.

Anyway, I found it.

Yes, a “quit delay” is probably the best work-around. This is not the first issue where I wished the scripting system would let the scripted app know when the script has ended (like, really been closed) for proper cleanup actions.

Thanks for all your help. I am not expecting to implement this right away, but if I do, I’ll share.

A suitable way is to set a timer (preferable a dispatch timer because it can be easily restarted) in the delegateHandlesKey: method and call [NSApp terminate:self] in the dispatch event handler when the timeout is reached. A reference to the script is not needed.

Deprecated Carbon APIs are still deprecated, as far as I can see. The OSA C API documentation is still in the legacy section. The Apple Event Manager C API documentation is now showing up in the active section where previously it was in the legacy section. Bizarrely the legacy section Component Manager C API documentation is also showing in the active section even though all its APIs are deprecated (10.8+), so I can’t help wondering if the documentation people have pushed the wrong button somewhere and shunted a bunch of legacy documentation into the active section by accident.

(The only justification I can think of for de-legacying the Carbon AEM would be if Adobe or MS indicated they weren’t going to continue AS support unless there was a hard guarantee Apple won’t randomly do to the Carbon AEM APIs what they already did to the Carbon GUI APIs; because, surprise, app vendors don’t like being burned any more than end users do. But honestly, I think all three parties would be delighted to be given any excuse to ditch AS, so this doesn’t seem all that likely to me.)

Although even if the de-legacy of AEM APIs is intentional, it still isn’t good news because it all it means that Apple is now completely directionless as far as scripting and IPC is concerned. At least when they added the missing APIs to NSAppleEventDescriptor it was a sign they were going in the direction of forward (albeit by a laughably trivial amount). Going backwards does not inspire confidence; and frankly no-one in their right mind codes against old Carbon APIs like these unless they absolutely have no choice as they are incredibly arcane and crusty. And with the massive rise of Swift they’re now even more painful to work with than they were in [Obj]C “ and they were already pretty horrible there. It’s bad enough gluing Cocoa to Swift; if they’re now trying to glue Carbon to it too then they’ve completely lost the plot.

So do you have any reference or communication that shows the move of legacy API documentation back to the active section was done deliberately and for what reason, and not just a minor administrative error of the sort that invariably happens in any large organizations? Not that it makes all that much difference to me (what’s done remains done), but it’d be good to get the record straight for other people’s benefit.

For JSON, see NSJSONSerialization which you can use via the AppleScript-ObjC bridge. e.g. The “standard” libraries I’ve been slowly working on the last few months include encode JSON and decode JSON command that put a more AppleScript-friendly face on the raw Cocoa APIs. They’re not quite done - testing and documentation is incomplete - but I’m currently seeing about handing them off to someone else to distribute and support better than I can, so hopefully that’ll give us the kick in the pants needed to finish it off.

This was posted to Apple’s Applescript mailing list earlier this year by one of the engineers (Chris Nebel):

And to echo what Shane says, writing new osaxen is likely not a good investment. I’m surprised Apple hasn’t dropped the ax already, given their supposed concern for system security. The OSAX system was a quick-n-dirty code injection mechanism, thrown together to partly make up for AS’s lack of a native extension API, back in the days before Mac security was even a thing. Had Apple not then scrapped the original AS team, it’d have most likely been superseded by something far more capable and safe long before now.

While AS libraries have their own sets of problems, they’re still a better choice and about as well future-proofed as AS itself. And of course there’s nothing to prevent an AS library wrapping an ObjC framework itself (other than the usual issues with importing new stuff into an ObjC runtime) if it really needs to do the bulk of the work in [Obj]C.

Thanks Shane. Obviously I missed that post; do you have a URL for the mailing list archives?

Though I don’t know what Chris means by “certain amount of confusion about AEM’s status”, as the legacy section was perfectly clear about what “legacy” status meant: software that already used these old APIs could continue to do so as they weren’t going away any time soon, but developers should avoid building new products on them but use newer Cocoa APIs instead.

And frankly, given the vast incoherent sprawl of archaic, half-assed, unloved, and poorly understood APIs that the AS team already can’t maintain or support worth a damn, I don’t think resurrecting an already functionally deceased API is going to do the AppleScript platform the slightest damn favor. They should be going through all that garbage with a flamethrower, classic Steve Jobs-style, until only the hardiest essential growth remains, ready to grow anew, not hauling back all its useless rotting semi-corpses to chomp on even more brains than they already have.

But then, Never mind the quality, just feel the width! has been this current AS team’s motto for years now, while the entire platform’s slow, sad slide into a mostly moribund and increasingly irrelevant state proceeds unabated. (Not that they’ll ever work out what the real problem is, but then that would require a mirror.)

This is where my post was based on. But like I said, undeprecation of the AEM doesn’t the flaws of osaxen are away, they’re still in there.

For the record: Osaxen loaded into an remote application needs to be approved (only used the first time) by the end-user, to be clear it’s not possible to inject code in any kind of arbitrary process without notifying the end-user as some people claim is possible. Osaxen are flawed from all angles, I agree on that, but the code injection part has been addressed in multiple updates and new osaxen designs since Leopard.

True, first ignoring a problem and make it legacy. Still using it as the main IPC in the for opening, quitting and printing and more standard events. Then all the sudden undo it all. It feels to me that the person in charge for writing the documentation was way behind on schedule :wink: . It was always strange to me because the documentation in the OSA header files were updated and changed through different OS versions so it was never actually deprecated (read: unsupported) entirely which led to some discussions here as well.

If I made a scriptable faceless bg app, where would I place it so that it gets automatically found when using it in a script with a tell command? Is ~/Library/ScriptingAdditions still the right place for that? Mind you, I don’t want to put it into /Applications as it would only confuse the user.

Or is there even a way to have it auto-routed to the right place (that used to be a thing back in the days but isn’t any more for most types nowadays, I just realize. Though, some types, such as Automator actions, still get moved when opening them, right?)

I would say in /Applications

A faceless app? Nope. What would you say if you double clicked it and nothing happened? Bad idea.

I could mak it so that if it does not receive any scripting call within a second, it would pop up a message telling the user that it’s not doing anything other than being there for scripting. But it would still not belong in /Applications as it would clutter the folder needlessly and would probably also appear in the Launcher where it doesn’t belong either.

Because someone has no clue what he has installed on his system? If the application is double clicked you could show a splash window explaining what the application does, if the application was launched by script you won’t show it.

A person who installs your app on purpose is supposed to have basic AppleScript knowledge and will understand the concept of a faceless application. :wink: