AppleScript / Swift / System Events

Good evening,


I have been scouring the forums (and others) for a few days, and can't quite seem to find a definitive answer to this, so wanted to message and check for my specific instance.


I have created a Mac app that is running AppleScript (i.e. push a button and it triggers).

It works perfectly under notarisation / 'hardened runtime'...


The issue however, is that when I introduce sandboxing (the idea of sandboxing in this instance being for both security purposes, as well as posting to the mac app store), it stops functioning as it either:

- doesn't think System Events is running

OR

- a permissions issue occurs


From exploration, in order to run a script in a sandboxed enviroment you can use:

- temporary exception entitlement (which is largely prohibited from the app store, and therefore not desirable in this instance)

OR

- scripting targets: com.apple.security.scripting-targets


Apple provide an app for Mail:

<key>com.apple.security.scripting-targets</key>

<dict>

<key>com.apple.mail</key>

<array>

<string>com.apple.mail.compose</string>

</array>

</dict>


On page: https://developer.apple.com/library/archive/documentation/Miscellaneous/Reference/EntitlementKeyReference/Chapters/EnablingAppSandbox.html


However I am trying to understand if / how this could be used with System Events, e.g.


<key>com.apple.security.scripting-targets</key>

<dict>

<key>com.apple.systemevents</key>

<array>

<string>com.apple.systemevents.WHATEVER</string>

</array>

</dict>


And if so, how would I go about finding the list of 'Scripting access groups' for System Events?


Further question - If there is not a set of 'Scripting access groups' available for System Events, does this therefore mean that it is impossible to call System Events from a Sandboxed app?


Thank you in advance for your support.

Replies

However I am trying to understand if / how this could be used with System Events

The trick here is to use the

sdef
tool to get the scripting definition of the target app to see if it contains any useful scripting targets. For example, on 10.14.6 this command:
$ sdef /Applications/iTunes.app

has a bunch of access groups (

com.apple.iTunes.playback
,
com.apple.iTunes.library.read
,
com.apple.iTunes.library.read-write
, and so on). If, however, you do the following for Scripting Events:
$ sdef "/System/Library/CoreServices/System Events.app"

you’ll see it defines only one (

com.apple.systemevents.window.position
).

If there is not a set of 'Scripting access groups' available for System Events, does this therefore mean that it is impossible to call System Events from a Sandboxed app?

No. You can always use the temporary entitlement (although that will almost certainly not be allowed on the Mac App Store). You can also use

NSUserScriptTask
, but your focus must be on supporting general-purpose attachability, not just use this as a way to bypass the App Sandbox.

Share and Enjoy

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

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

Why? System Events is just a clunky old wrapper around a bunch of public [Obj]C system APIs. Since you’re already in ObjC/Swift just ditch the AS middleman and call those APIs directly.

  • Could you expand on this? I developed an app that can’t function without the temporary exception entitlement for System Events. This has prevented it from being approved for the App Store. (An earlier version was approved WITH the exception, but they are no longer granting it.)

    I have been working with Apple code-level support to see if there is any other way other than using AppleScript and System Events to access the information I need, but they state flatly that the only way to do it is the way I'm already doing it. There are no public APIs that can replace the functionality of AppleScript and System Events.

    In my case particular case, I need to track the position on screen and the precise dimensions of the Dock, which is a System Events process. My Swift app can pull this data using AppleScript handlers via the Obj-C/AppleScript bridge, but I see no way to avoid telling System Events in the handlers.

    If you know of perhaps unpublished public APIs that could be called directly, I’m all eyes!

Add a Comment

Thank you very much for your reply - having reviewed the relevant documentation and other forums it had seemed like this was the case... So many people seem to be exploring this, so I wanted to check in re viability.


Many thanks!

Honestly, mostly curiosity... 🙂


I had seen that loads of people were exploring different ways to access System Events from a sandbox (specifically to post the result on the Mac App Store), so I just wanted to verify that this was viable or not.


So basically I chucked together a bit AppleScript, and ran through the likely ways you could get it to work in an App Store compliant sandbox (of course it didn't). At that point I just wanted to make sure I wasn't missing something obviuous 🙂


As you say, in reality, there are better ways of doing things.


Many thanks

For third-party apps, if the app’s sdef file (assuming it has one) doesn’t already define appropriate scripting targets then you can always file a feature request asking for them to be added. Ditto for Apple apps if there aren’t already system APIs to the same functionality.


To be frank, Apple event sandboxing and security retrofitting is all rather half-baked and under-documented, so it’s not surprising many people are thrashing about for clarity and answers. Unfortunately, years of neglect and mismanagement have relegated Apple event technologies to maintenance mode and the original development team disbanded, so it’s unknown what, if any, plans Apple has to remedy this in future… or even if Apple event automation has a long-term future at all. The one Automation technology Apple clearly is investing in is app extension-based conversational shortcuts on iOS, so with Shortcuts for Mac looking to arrive in 10.16 let us hope it brings clarity at last. Meantime, the safest advice I can offer is that for any investor: just don’t put in more than you’re willing to lose.