【问题标题】:PassthroughSubject completion finished not calledPassthroughSubject 完成完成未调用
【发布时间】:2021-02-18 11:09:17
【问题描述】:

我正在尝试使用 Combine 与 CoreBluetooth 通信,但我的 PassthroughSubject 完成处理程序没有被调用。您可以在下面看到代码的粗略布局。 DetailViewModel 包含蓝牙外设和要发送的数据。

final class DetailViewModel: NSObject, ObservableObject, CBPeripheralDelegate {
    // Called when the correct write characteristic is found
    private var writeCharacteristicReceived = PassthroughSubject<CBCharacteristic, Never>()
    // Used to send and listen for peripheral data
    private var bluetoothDidChange = PassthroughSubject<Data, Error>()

    func open() -> AnyPublisher<Data, Error> {
        writeCharacteristicReceived.tryMap { characteristic -> AnyPublisher<Data, Error> in
            print("Write char", characteristic)

            let data: Data = try constructPayload()

            self.peripheral?.writeValue(data, for: characteristic, type: .withoutResponse)

            return self.bluetoothDidChange.eraseToAnyPublisher()
        }
        .switchToLatest()
        .eraseToAnyPublisher()
    }

    func peripheral(_ peripheral: CBPeripheral, didUpdateValueFor characteristic: CBCharacteristic, error: Error?) {
        print("Did update value", characteristic.value ?? Data())
        guard let value = characteristic.value, value.count >= 84 else { return }

        defer {
            // Never called
            bluetoothDidChange.send(completion: .finished)
        }

        do {
            let message: Data = try parse(value)
            bluetoothDidChange.send(message)
            // Never called when placed here either
            // bluetoothDidChange.send(completion: .finished)
        } catch {
            bluetoothDidChange.send(completion: .failure(error))
        }
    }
}

然后我在视图本身中监听这些变化,如下所示

viewModel.open().sink(receiveCompletion: { (completion) in
    print("Open completion: \(completion)")
}, receiveValue: { (payload) in
    print("Open payload \(payload)")
}).store(in: &cancellable)

现在,这适用于不时接收值,并且在发生错误时正确调用完成块。但我从来没有得到完成的完成处理程序,即使我专门做send(completion: .finished)。谁能帮帮我?

【问题讨论】:

    标签: swift swiftui core-bluetooth combine publisher


    【解决方案1】:

    与从未调用过的writeCharacteristicReceived.send(completion: .finished) 相关的问题。将其添加到委托调用的函数中解决了该问题。

    func peripheral(_ peripheral: CBPeripheral, didDiscoverDescriptorsFor characteristic: CBCharacteristic, error: Error?) {
        if let error = error {
            writeCharacteristicDiscovered.send(completion: .failure(error))
        }
        writeCharacteristicDiscovered.send(characteristic)
        writeCharacteristicDiscovered.send(completion: .finished)
    }
    

    【讨论】:

    • "...在正确的位置",请填写您的答案,包括需要帮助其他人寻找类似解决方案的代码。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-11-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-08-16
    相关资源
    最近更新 更多