Swift 有没有一种方法可以获得ping的结果,显示在文本框中,但不使用旋转的色轮?

Swift 有没有一种方法可以获得ping的结果,显示在文本框中,但不使用旋转的色轮?,swift,cmd,process,ping,Swift,Cmd,Process,Ping,由于ping的结果可能需要4秒以上(取决于跳数),因此我得到了旋转的色轮(beachball),它通常表示程序已锁定或无法运行 应用程序继续旋转色轮,并在文本框中显示结果。有办法摆脱“海滩球”吗 我通过将结果打印到每个变量进行调试。 执行“let handle1=pipe.fileHandleForReading”后,beachball将显示。 我试过大中央调度(GCD),但仍然得到同样的结果 // Built using X-Code Version 8.2.1 - Swift Version

由于ping的结果可能需要4秒以上(取决于跳数),因此我得到了旋转的色轮(beachball),它通常表示程序已锁定或无法运行

应用程序继续旋转色轮,并在文本框中显示结果。有办法摆脱“海滩球”吗

我通过将结果打印到每个变量进行调试。 执行“let handle1=pipe.fileHandleForReading”后,beachball将显示。 我试过大中央调度(GCD),但仍然得到同样的结果

// Built using X-Code Version 8.2.1 - Swift Version 3.0.2

// Text view for results (display)
@IBOutlet weak var Results: NSTextField!

// Start button to execute ping
@IBAction func startButton(_ sender: Any)
{
    cmdPing()
}

// Global variables
var myArg = ""
var shellResults = ""

func cmdPing()
{
    // Step 1
    myArg = "ping -c 10 www.google.com"
    shellResults = getPing(shellArgs: myArg)
    Results.stringValue = shellResults

    // Step 2
    myArg = "ping -c 10 127.0.0.1"
    shellResults = getPing(shellArgs: myArg)
    Results.stringValue = shellResults

}


// function that executes a shell command and returns its value (myArg)
func getPing(shellArgs: String) -> String
{
    let task:Process = Process()
    let pipe:Pipe = Pipe()
    task.launchPath = "/bin/sh"
    task.arguments = ["-c", shellArgs]
    task.standardOutput = pipe
    task.launch()
    let handle1 = pipe.fileHandleForReading
    let data1 = handle1.readDataToEndOfFile()
    let result1 = NSString(data: data1, encoding: String.Encoding.utf8.rawValue)
    let trimmed1 = (result1! as NSString).trimmingCharacters(in: NSCharacterSet.whitespaces)
    shellResults = trimmed1
    task.waitUntilExit()
    return shellResults
}

我确实在文本框中得到了结果。如果能够做到这一点,最好是在每次ping期间在文本框中显示每一行(跃点),而不显示“海滩球”。任何帮助都将不胜感激。

这就是有效的方法。它将执行一个命令并返回textview或scrollview窗口中的每个跃点。这将摆脱旋转的“沙滩球”。添加了一个计数器,或者您可以执行循环以继续执行许多任务(命令ping)

func getPing(shell参数:字符串)
{
让任务=进程()
task.launchPath=“/bin/sh”
task.arguments=[“-c”,shell参数]
让管道=管道()
task.standardOutput=管道
let outHandle=pipe.fileHandleForReading
outHandle.waitForDataInBackgroundAndNotify()
var obs1:NSObjectProtocol!
obs1=NotificationCenter.default.addObserver(forName:NSNotification.Name.NSFileHandleDataAvailable,对象:outHandle,队列:nil)
{
通知->在let data=outHandle.availableData中无效
如果data.count>0
{
如果let str=NSString(数据:数据,编码:String.encoding.utf8.rawValue)
{
//在结果(文本视图)窗口中放置数据(str)
self.Results.stringValue+=“\(str)”
}
outHandle.waitForDataInBackgroundAndNotify()
}
其他的
{
打印(“来自进程的标准输出上的EOF”)
NotificationCenter.default.removeObserver(obs1)
}
}
var obs2:NSObjectProtocol!
obs2=NotificationCenter.default.addObserver(forName:Process.didTerminateNotification,object:task,queue:nil)
{
通知->打印无效(“已终止”)
NotificationCenter.default.removeObserver(obs2)
如果self.pingCount<3
{
//添加计数器并继续执行其他命令(步骤)
self.pingCount+=1
self.cmdPing()
}
其他的
{
//结束任务
任务终止()
}
}
task.launch()
}

多亏Patrick F找到了我问题的答案。从线程:使用Swift[link]()将实时NSTask输出到NSTextView
func getPing(shellArgs: String)
{

    let task = Process()
    task.launchPath = "/bin/sh"
    task.arguments = ["-c", shellArgs]

    let pipe = Pipe()
    task.standardOutput = pipe
    let outHandle = pipe.fileHandleForReading
    outHandle.waitForDataInBackgroundAndNotify()

    var obs1 : NSObjectProtocol!
    obs1 = NotificationCenter.default.addObserver(forName: NSNotification.Name.NSFileHandleDataAvailable, object: outHandle, queue: nil)
    {
        notification -> Void in let data = outHandle.availableData

        if data.count > 0
        {
            if let str = NSString(data: data, encoding: String.Encoding.utf8.rawValue)
            {
                // place data (str) in Results (textview) window
                self.Results.stringValue += "\(str)"
            }
            outHandle.waitForDataInBackgroundAndNotify()
        }
        else
        {
            print("EOF on stdout from process")
            NotificationCenter.default.removeObserver(obs1)
        }
    }

    var obs2 : NSObjectProtocol!
    obs2 = NotificationCenter.default.addObserver(forName: Process.didTerminateNotification, object: task, queue: nil)
    {
        notification -> Void in print("terminated")
        NotificationCenter.default.removeObserver(obs2)
        if self.pingCount < 3
        {
            // add counter and continue for other commands (steps)
            self.pingCount += 1
            self.cmdPing()
        }
        else
        {
            // end task
            task.terminate()
        }
    }
    task.launch()
}