在斯威夫特听斯坦丁

时间:2018-04-10 08:08:22

标签: swift swift4 stdin

目前我正在尝试在swift应用程序中从命令行监听用户输入。

我知道readLine()方法但它并不真正符合我的需要。我想监听在命令行中插入的数据。就像用户按下终端内的“向上键”一样。

可以在Node.js中完成的任务:

stdin.on( 'data', function( key ){ 
    if (key === '\u0003' ) {
        process.exit();   
    }   // write the key to stdout all normal like                 

    process.stdout.write( key ); 
});

我试过搜索但是在Swift中找不到相同的东西。我想也许是“输入流”的东西,但也找不到合适的解决方案。

如果有人能给我一些关于如何在Swift中做这样的事情的提示,我会非常感激。

2 个答案:

答案 0 :(得分:2)

您可能想要FileHandle.standardInput

类似的东西:

let file = FileHandle.standardInput

while true {
    let data = file.availableData
    print("\(String(bytes: data, encoding: .utf8))")
}

将按照我想要的方式回应输入。标准免责声明关于小心输入,这可能是一个危险的活动,消毒你的输入等等。

我不确定您是如何选择匹配特定控件和箭头键的,但这是一个开始。

答案 1 :(得分:2)

通常标准输入会缓冲所有内容,直到输入换行符,这就是为什么行读取典型标准输入的原因:

while let line = readLine() {
   print(line)
}

(按CTRL + D发送EOF,即结束输入)

要真正分别读取每个字符,您需要进入原始模式,这意味着使用低级终端功能:

// see https://stackoverflow.com/a/24335355/669586
func initStruct<S>() -> S {
    let struct_pointer = UnsafeMutablePointer<S>.allocate(capacity: 1)
    let struct_memory = struct_pointer.pointee
    struct_pointer.deallocate() 
    return struct_memory
}

func enableRawMode(fileHandle: FileHandle) -> termios {
    var raw: termios = initStruct()
    tcgetattr(fileHandle.fileDescriptor, &raw)

    let original = raw

    raw.c_lflag &= ~(UInt(ECHO | ICANON))
    tcsetattr(fileHandle.fileDescriptor, TCSAFLUSH, &raw);

    return original
}

func restoreRawMode(fileHandle: FileHandle, originalTerm: termios) {
    var term = originalTerm
    tcsetattr(fileHandle.fileDescriptor, TCSAFLUSH, &term);
}

let stdIn = FileHandle.standardInput
let originalTerm = enableRawMode(fileHandle: stdIn)

var char: UInt8 = 0
while read(stdIn.fileDescriptor, &char, 1) == 1 {
    if char == 0x04 { // detect EOF (Ctrl+D)
        break
    }
    print(char)
}

// It would be also nice to disable raw input when exiting the app.
restoreRawMode(fileHandle: stdIn, originalTerm: originalTerm)

参考https://viewsourcecode.org/snaptoken/kilo/02.enteringRawMode.html