I have a non-sandboxed macOS application that happily calls on shell scripts in its resource bundle with the following approach:
class func runShell(launchPath: String, arguments: [String] = [], waitUntilExit: Bool) -> Void {
let task = Process()
task.launchPath = launchPath
task.arguments = arguments
let pipe = Pipe()
task.standardOutput = pipe
task.launch()
if waitUntilExit {
task.waitUntilExit()
}
}
ABCProcessManager.runShell(launchPath: scriptPath.path, arguments: ["-workingdirectory", path], waitUntilExit: true)
I'm trying to convert the application to a sandboxed one (for App Store upload) but it freezes when it calls the scripts.
The scripts manage a launchagent. Loading, unloading, starting, stopping.
How do I need to change my code to make it work with the sandbox turned on? Maybe there is a "sandboxed way" of managing launch agents?
I found an answer on Apple Support forums posted by an Apple staff member:
Is is possible to have applications in the Mac App Store that work with LaunchAgents?
No.
Why not:
- XPC Services included within an app are only available to that app.
- Mac App Store apps are not allowed to include a launchd daemon or agent.
They also mention that technically there is one undocumented way, but strongly recommend against going down that path:
As an accident of the implementation, the service registered by a sandbox-compatible login item is visible to other processes running in the user’s session. So on current systems you could make this work by implementing a sandbox-compatible login item (as illustrated by the AppSandboxLoginItemXPCDemo sample code) and have your command-line tools talk to it. The problem with this approach is that it’s an accident of the implementation rather than a documented feature. Moreover, it runs counter to the general App Sandbox goal that a sandboxed app should be isolated from the rest of the system.
So I guess I will be sticking with a non-sandboxed application distributed directly to customers.