How to run AppleScript from C++ in macOS sandbox environment without entitlement violations

  applescript, appstore-sandbox, c++, macos, qt

I am trying to use AppleScript to control the Apple Photos app from within a QT C++ app that must run in the sandbox environment required for the macOS App Store.

I have tried to run the AppleScript via a QProcess launching osascript, like this :

const QString aScript = QString(
        "tell application "Photos"n"
        "    set selMedia to (get media items whose id contains "%1")n"
        "    if not (album "Trash from %2" exists) thenn"
        "        make new album named "Trash from %2"n"
        "    end ifn"
        "    add selMedia to album "Trash from %2"n"
        "end tell").arg(fileNameNoExt, APP_NAME);
QProcess script;
script.setProgram("osascript");
script.setArguments(QStringList() <<
                     "-e" << aScript);
script.start();
script.waitForFinished(); 
int exitCode = script.exitCode();
if(exitCode!=0){
    QString outMsg = script.readAllStandardOutput();
    QString errorOut = script.readAllStandardError();
    // Warn user and output message... 
}

This works fine outside the sandbox, adding the desired items from the library to the desired album. However, inside the sandbox, I get an errAEPrivilegeError. Looking in the Console for the error event, it states :

AppleEvents/sandbox: Returning errAEPrivilegeError/-10004 and denying dispatch of event core/getd from process '<private>'/0x0-0x4d84d8, pid=31654, because it is not entitled to send an AppleEvent to this process.

Here is my entitlements file when signing the app :

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
  <dict>
    <key>com.apple.security.files.user-selected.read-write</key>
        <true/>
    <key>com.apple.security.app-sandbox</key>
        <true/>
    <key>com.apple.security.scripting-targets</key>
    <dict>
        <key>com.apple.Photos</key>
        <array>
            <string>com.apple.Photos.library.read-write</string>
        </array>
    </dict>
  </dict>
</plist>

When the app is first run (sandboxed) and the AppleScript is started, I get the system permission box, saying that the app is asking to control the Photos app. I click OK of course, but then I get the error. And upon next runs, as the permission is already granted, no system permission box comes up, but it fails nonetheless. When I reset the permissions with the terminal command tccutil reset All [my app bundle id], then upon the next execution of the app and the AppleScript, I get the permission box again.

If I delete the com.apple.security.scripting-targets entitlement, I get no system permission request and the error is different : from my app the error output states Photos isn’t running, from the console it says it was denied due to sandboxing. If I keep the scripting-targets and com.apple.Photos but delete library.read-write I get the errAEPrivilegeError again.

I have tried to only test the make new album named "Trash [...]"but this still fails with errAEPrivilegeError.

Also, if I try to run the qprocess not as a separate process, with QProcess::execute (if maybe the sandbox problem is because it is not the main app running the script ?), I still get the same errAEPrivilegeError.

What am I missing for it to work, or what other method should I use to run an applescript from C++/QT when in a sandbox ?

Source: Windows Questions C++

LEAVE A COMMENT