Benjamin Schmidt
Benjamin Schmidt

Reputation: 1061

NSWorkspace.OpenConfiguration ignores arguments despite not being sandboxed

I'm trying to launch an application using the open tool through Swift. I have two seperate implementations, one with NSWorkspace.shared.openApplication(at:configuration) for 10.15+ and one with NSWorkspace.shared.launchApplication(at:options:configuration) for 10.14 and lower. Everything works fine on 10.14 and below but Catalina is ignoring any arguments thrown at it. The app is not sandboxed.

Implementation for 10.15+:

let appPath = URL(string: "file:///usr/bin/open")!
let configuration = NSWorkspace.OpenConfiguration()
configuration.arguments = [
    "-a",
    executablePath,
    url.absoluteString
]

NSWorkspace.shared.openApplication(at: appPath, configuration: configuration) { (app, error) in
    if let error = error {
        done(error)
    } else {
        done(nil)
    }
}

Running this results in a Terminal window opening /usr/bin/open with no arguments, then closing the session.

Catalina opening a Terminal

executablePath is a string to an application's executable, e.g. /Application/Safari.app/Contents/MacOS/Safari

url is a URL object containing an http or https link

Removing file:// from appPath also works fine in 10.14, but on 10.15 results in The application “open” could not be launched because a miscellaneous error occurred.

Am I missing something?

Upvotes: 4

Views: 1952

Answers (1)

Benjamin Schmidt
Benjamin Schmidt

Reputation: 1061

I have worked around this problem in a different way. Instead of using NSWorkspace.shared.openApplication(at:configuration:) I'm now invoking a Process that opens open.

This also works on versions below Catalina and even works with sandboxing. However, there's a catch to sandboxing, read more at the end.

Workaround

let task = Process()
        
task.arguments = ["-a", executablePath, url.absoluteString]
task.launchPath = "/usr/bin/open"
task.launch()

No need for waiting for the process as a) the return of open isn't that useful and b) it's almost immediately anyway.

Regarding Sandboxing

Apple states:

In a sandboxed application, child processes created with the Process class inherit the sandbox of the parent app.

This means that the application opened using Process has the same sandbox. If you use open to open a URL like I do that's fine because open spawns a new process without our sandbox anyway. However this does mean that you cannot use this open other regular apps unless this app is working fine with your sandbox.

Upvotes: 1

Related Questions