I am maintaining a macOS app, a GUI on top of a command line tool. A Process() object is used to kick off the command line tool with arguments. And completion handlers are triggered for post actions when command line tool is completed. My question is: I want to refactor the process to use async and await, and not use completion handlers.
func execute(command: String, arguments:[String]) -> async {
let task = Process()
task.launchPath = command
task.arguments = arguments
...
do {
try task.run()
} catch let e {
let error = e
propogateerror(error: error)
}
...
}
...
and like this in calling the process
await execute(..)
Combine is used to monitor the ProcessTermination:
NotificationCenter.default.publisher(
for: Process.didTerminateNotification)
.debounce(for: .milliseconds(500), scheduler: DispatchQueue.main)
.sink { _ in
.....
// Release Combine subscribers
self.subscriptons.removeAll()
}.store(in: &subscriptons)
Using Combine works fine by using completion handlers, but not by refactor to async. What is the best way to refactor the function? I know there is a task.waitUntilExit()
, but is this 100% bulletproof? Will it always wait until external task is completed?