使用 Swift 将 NSTask 实时输出到 NSTextView [英] Real time NSTask output to NSTextView with Swift
问题描述
我正在使用 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屋!