0

我正在尝试将 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 )

        }
    }
}
4

0 回答 0