使用 ORSSerialPort 从 Swift 4 中的串行端口读取

Read from a serial port in Swift 4 using ORSSerialPort

我一直想制作一个应用程序,通过串口向我的 LED 控制器发送指令。为此,我需要读取控制器在发送命令后发回的内容。我在 ORSSerialPort 中找到了以下函数:

func serialPort(_ serialPort: ORSSerialPort, didReceive data: Data) {
    // Do things
}

但是,有没有类似ORSSerialPort.read()的东西?

我认为 ORSSerialPort.read() 不是个好主意。我知道其他一些串行库是以这种方式编写的,但唯一的工作方式是 read() 阻塞(可能有超时),直到一个字节进入端口。阻塞 I/O 使得编写良好的响应式应用程序变得更加困难,我想引导使用 ORSSerialPort 的开发人员远离这种方法。

相反,您确实应该在 ORSSerialPort 委托中实现 serialPort(_:, didReceive:)。当串行端口接收到数据时,将使用接收到的数据调用该方法,你可以用它做任何你想做的事情。

也就是说,如果您的设备使用 command/response 类型的协议进行通信(即每次发送命令时,设备都会发送一些响应),您应该查看 ORSSerialPort 的 request/response API。它允许您显式定义命令的预期响应格式,而 ORSSerialPort 本身将异步处理等待、解析和验证响应。有关 ORSSerialPort 的这一部分的更多信息,请参阅 the documentation。该库还包括一个示例项目 RequestResponseDemo,演示如何使用此 API。 Swift 和 Objective-C 版本都包括在内。

ORSSerialPort 库很受欢迎,而且总体上很好。但是,我发现它不适用于 TTY 串行设备。这主要是因为它使用 IOKit 来发现串行端口——它只会发现物理设备。

这在您的情况下可能没问题,但如果您想测试代码但又不想连接到物理设备,它就会失败。好的代码总是需要一个测试框架。因此,查看 https://github.com/kpishere/POSIXSerialPort 一个非常简单的串行接口 API 它正是您编写和响应传入数据所需要的,并且还可以与物理或虚拟设备一起使用(正如 Unix 最初设想的那样!)。

不过对于您的问题,您不想直接调用 read()。您开始了解“这是阻塞读取吗?”然后你开始处理线程。建议的两个 API 都将您与此隔离开来,并允许您根据事件驱动模型进行思考——这使得代码更简单。