使用 Swift 将 NSTask 实时输出到 NSTextView [英] Real time NSTask output to NSTextView with Swift

查看:55
本文介绍了使用 Swift 将 NSTask 实时输出到 NSTextView的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用 NSTask 来运行 rsync,并且我希望状态显示在窗口内滚动视图的文本视图中.现在我有这个:

I'm using an NSTask to run rsync, and I'd like the status to show up in the text view of a scroll view inside a window. Right now I have this:

let pipe = NSPipe()
task2.standardOutput = pipe
task2.launch()

let data = pipe.fileHandleForReading.readDataToEndOfFile()
let output: String = NSString(data: data, encoding: NSASCIIStringEncoding)! as String

textView.string = output

这让我获得了有关传输的一些统计信息,但我想实时获取输出,例如在 Xcode 中运行应用程序时打印出的内容,并将其放入文本视图中.有没有办法做到这一点?

And that get's me the some of the statistics about the transfer, but I'd like to get the output in real time, like what get's printed out when I run the app in Xcode, and put it into the text view. Is there a way to do this?

推荐答案

(参见 Patrick F. 的回答 用于 Swift 3/4 的更新.)

(See Patrick F.'s answer for an update to Swift 3/4.)

您可以使用通知从管道异步读取.这是一个简单的例子,演示它是如何工作的,希望帮助您入门:

You can read asynchronously from a pipe, using notifications. Here is a simple example demonstrating how it works, hopefully that helps you to get started:

let task = NSTask()
task.launchPath = "/bin/sh"
task.arguments = ["-c", "echo 1 ; sleep 1 ; echo 2 ; sleep 1 ; echo 3 ; sleep 1 ; echo 4"]

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

var obs1 : NSObjectProtocol!
obs1 = NSNotificationCenter.defaultCenter().addObserverForName(NSFileHandleDataAvailableNotification,
    object: outHandle, queue: nil) {  notification -> Void in
        let data = outHandle.availableData
        if data.length > 0 {
            if let str = NSString(data: data, encoding: NSUTF8StringEncoding) {
                print("got output: \(str)")
            }
            outHandle.waitForDataInBackgroundAndNotify()
        } else {
            print("EOF on stdout from process")
            NSNotificationCenter.defaultCenter().removeObserver(obs1)
        }
}

var obs2 : NSObjectProtocol!
obs2 = NSNotificationCenter.defaultCenter().addObserverForName(NSTaskDidTerminateNotification,
    object: task, queue: nil) { notification -> Void in
        print("terminated")
        NSNotificationCenter.defaultCenter().removeObserver(obs2)
}

task.launch()

代替 print("got output: \(str)") 你可以附加收到的字符串到您的文本视图.

Instead of print("got output: \(str)") you can append the received string to your text view.

上面的代码假设一个runloop是活动的(就是这种情况在默认的 Cocoa 应用程序中).

The above code assumes that a runloop is active (which is the case in a default Cocoa application).

这篇关于使用 Swift 将 NSTask 实时输出到 NSTextView的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆