I am a SwiftUI learner. Trying to run a simple function on MacOS, that stdout on view just like console. With below code it prints output on view once the execution gets finished. Is there anyway that I can redirect output to view realtime? Please help me. Thanks in advance!
struct MainView : View {
@State var Log : String = ""
var body: some View {
VStack {
Form {
Section {
Text("\(Log)")
}
.onAppear {
DispatchQueue.global(qos: .background).async {
Task {
let output = await self.runCodeAsync()
DispatchQueue.main.async {
Log.append(output)
}
}
}
}
}
}
}
func runCodeAsync() async -> (String) {
let task = Process()
task.executableURL = URL(fileURLWithPath: "/sbin/ping")
task.arguments = [ "-c", "3", "127.0.0.1" ]
let outputPipe = Pipe()
task.standardOutput = outputPipe
await task.launch() //Xcode Warning: no 'async' operations occur within 'await' expression
let outputData = outputPipe.fileHandleForReading.readDataToEndOfFile()
let output = String(decoding: outputData, as: UTF8.self)
return await output //Xcode Warning: no 'async' operations occur within 'await' expression
}
}
CodePudding user response:
try the following code, without using async:
EDIT-1:
struct MainView: View {
@State var log: String = "testing"
var body: some View {
Text(log)
.onAppear {
runCode()
}
.frame(width: 444, height: 444)
}
func runCode() {
let task = Process()
task.executableURL = URL(fileURLWithPath: "/sbin/ping")
task.arguments = [ "-c", "3", "127.0.0.1" ]
let outputPipe = Pipe()
task.standardOutput = outputPipe
let outputHandle = outputPipe.fileHandleForReading
outputHandle.readabilityHandler = { pipe in
if let ouput = String(data: pipe.availableData, encoding: .utf8) {
if !ouput.isEmpty {
log = " " ouput
print("----> ouput: \(ouput)")
}
} else {
print("Error decoding data: \(pipe.availableData)")
}
}
task.launch()
}
}
