I have a similar problem, on a new Mac Pro, but even worse. With macOS 10.15.3 Catalina I am not able to get system_profiler data for "SPAudioDataType". Other processes like curl etc. can be called but system_profiler is a problem.
The very funny thing with my problem was, that is only occurred about 10 minutes after making a fresh restart. In the first 10 minutes everything worked, with or without using handlers and even with the code "getApplications" from the answer above.
And yes, of course I run it in the main thread, but it makes no difference running in main thread or not.
I experimented lot to look, what is the source for this behavior. I found out, that my programs hangs while reading data with the command
let data = taskOutput.fileHandleForReading.readDataOfLength(1024)
in the case that there is error data available and vice versa the program hangs while reading error messages with the command
let data = taskError.fileHandleForReading.readDataOfLength(1024)
in the case that there is normal data available (but no error data).
The Program even hangs if I tried to get the amount of data, which is currently available:
let c = taskError.fileHandleForReading.availableData.count
Regardless what I test first, the program hangs if there is no data available.
So I completely rewrote my function to using async handlers:
@discardableResult func launchprogram (_ launchpath: String, _ arguments: [String]) -> (result: String, error: Int)
{
var out: String = "" // Output
var err: String = "" // Error Messages
var fin: Bool = false // If the process exits normally
let pro: Process = Process()
pro.arguments = arguments
pro.launchPath = launchpath
pro.standardOutput = Pipe()
pro.standardError = Pipe()
let proOut: Pipe = pro.standardOutput as! Pipe
let proIn: Pipe = pro.standardError as! Pipe
proOut.fileHandleForReading.readabilityHandler =
{
pipe in
if let line = String(data: pipe.availableData, encoding: String.Encoding.utf8)
{
if line.count > 0 // Neuen Ausgabe-Text hinzufügen
{
out += line
}
}
}
proIn.fileHandleForReading.readabilityHandler =
{
pipe in
if let line = String(data: pipe.availableData, encoding: String.Encoding.utf8)
{
if line.count > 0 // Neuen Fehler-Text hinzufügen
{
err += line
}
}
}
pro.terminationHandler =
{
(process) in
fin = not(process.isRunning)
}
pro.launch()
pro.waitUntilExit()
if err == ""
{
if fin
{
return (out, 0)
}
else
{
return (out, -1)
}
}
else if out == ""
{
let message: String = "Error while executing:" + char(13) + char(13)
return (message + err, -2)
}
else
{
let message: String = char(13) + char(13) + "Error while executing:" + char(13) + char(13)
return (out + message + err, -3)
}
}
The fundamental difference between this function and the function "getApplications" from the last post is, that I use "handler" to manage the output und error message streams. This always works. Deployment Target can bei 10.9 or above. I did not test it with 10.8 and earlier. So my problem was, that in Catalina under some circumstances it is not longer possible to get the information in "normal" synchronous order but only async with using handlers. If I break the execution, I always be in something like "libsystem_kernel.dylibread" withe the calling function "Foundation_NSReadFromFileDescriptorWithProgress". I would be glad to know, if this is a Catalina issue (with a new Mac Pro) or a fundamental change in what Apple wants us to use.