PassthroughSubject 完成完成未调用
PassthroughSubject completion finished not called
我正在尝试使用 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)
也没有。谁能帮帮我?
与 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)
}
我正在尝试使用 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)
也没有。谁能帮帮我?
与 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)
}