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) then\n"
" make new album named \"Trash from %2\"\n"
" end if\n"
" 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. Even if only telling Photos to quit with AppleScript (which according to Photos.app/Contents/Resources/Photos.sdef doesn't require any specific permissions appart from scripting, I also get errAEPrivilegeError. The only command that seems to work is activate.
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 ?