我正在尝试将 ORSSerialPort 框架与 Combine 集成到 SwiftUi 中。ORSSerialPort GitHub
ORSSerialPort 实现 Key-Value Observing (KVO) 和委托模式。在他的示例中,他使用了委托模式和 UIKit。我将使用 Combine 和 SwiftUI。不是委托模式。
因为 ORSSerialPort 是一个 KVO 对象,所以应该可以订阅 ORSSerialPort 变量,但她是我的问题。不起作用。我不知道为什么。
我尝试什么:
@Published var isOpen: String = ""
var orsSerialPort: ORSSerialPort = ORSSerialPort(path: "/dev/cu.usbmodem146101")!
var publisher: NSObject.KeyValueObservingPublisher<ORSSerialPort, Bool>
var isOpenSub: AnyCancellable?
init(){
publisher = orsSerialPort.publisher(for: \.isOpen)
isOpenSub = publisher
.map{ (x) -> String in return "Is \(x ? "Opend":"Close" )" }
.assign(to: \.isOpen, on: self)
}
发布者总是被触发一次,那就是由 init 触发。如果我用我的函数关闭并打开端口,它将不会再次触发。
func cloes(){
orsSerialPort.close()
}
func open(){
orsSerialPort.open()
}
对于调试,我尝试使用 Stream。而且我会再次看到发布者总是只会触发一次。但港口正在关闭和开放。
.sink(receiveCompletion: { completion in
print("subScribeIsOpen complet")
switch completion {
case .finished:
print("subScribeIsOpen complet")
case .failure(let error):
print("subScribeIsOpen fail")
print(error.localizedDescription)
}
}, receiveValue: { value in
print("subScribeIsOpen receive \(value)")
self.isOpen = value
})
我的演示代码
import Foundation
import ORSSerial
import Combine
import SwiftUI
class ORSSerialPortCombine: ObservableObject {
@Published var status: String = ""
@Published var isOpen: String = ""
var orsSerialPort: ORSSerialPort = ORSSerialPort(path: "/dev/cu.usbmodem146101")!
var publisher: NSObject.KeyValueObservingPublisher<ORSSerialPort, Bool>
var isOpenSub: AnyCancellable?
init(){
publisher = orsSerialPort.publisher(for: \.isOpen)
isOpenSub = publisher
.map{ (x) -> String in return "Is \(x ? "Opend":"Close" )" }
// .assign(to: \.isOpen, on: self)
.sink(receiveCompletion: { completion in
print("subScribeIsOpen complet")
switch completion {
case .finished:
print("subScribeIsOpen complet")
case .failure(let error):
print("subScribeIsOpen fail")
print(error.localizedDescription)
}
}, receiveValue: { value in
print("subScribeIsOpen receive \(value)")
self.isOpen = value
})
}
func cloes(){
orsSerialPort.close()
}
func open(){
orsSerialPort.open()
}
func updateStatus(){
status = "Serial port is \(orsSerialPort.isOpen ? "Opend":"Close" )"
}
}
struct ORSSerialPortCombineView: View{
@ObservedObject var model = ORSSerialPortCombine()
var body: some View{
VStack{
Text( model.isOpen )
HStack{
Button("Close") { model.cloes() }
Button("Open") { model.open() }
Button("Staus") { model.updateStatus() }
}
Text( model.status )
}
}
}