Read followed by write
eddy93 opened this issue · 2 comments
eddy93 commented
I have two characteristics one to read a notification and a characteristic to write. Thing is I want to write once reading is successful. Right now i’m discovering both characteristics, but with no use of the write one. How can I turn around my code to write to the write characteristic once the read is successful?
viewDidShow.subscribe(onNext: { [weak self] _ in
guard let strongSelf = self else {return}
manager.observeStateWithInitialValue()
.filter {$0 == .poweredOn}
.flatMap { _ in manager.scanForPeripherals(withServices: [CBUUID.Device.mainService])}
.filter { $0.peripheral.identifier == userRepository.getSavedBottle()}
.flatMap { $0.peripheral.establishConnection() }
.flatMap { $0.discoverServices([CBUUID.Device.mainService]) }
.flatMap { Observable.from($0) }
.flatMap { $0.discoverCharacteristics([CBUUID.Device.readUUID, CBUUID.Device.writeUUID]) }
.flatMap { Observable.from($0) }
.flatMap { $0.observeValueUpdateAndSetNotification() }
.subscribe(onNext: {
if $0.uuid == CBUUID.Device.readUUID {
let value = $0.value?.withUnsafeBytes({(rawPtr: UnsafeRawBufferPointer) in
return rawPtr.load(as: UInt64.self)
})
print(value)
}
})
.disposed(by: strongSelf.disposeBag)
}).disposed(by: disposeBag)
minixT commented
Hi @eddy93,
you need to change your code a little. You need to save somehow write characteristic and use it after read operation. Here is an example how you can achieve this:
manager.observeStateWithInitialValue()
.filter {$0 == .poweredOn} // wait until bluetooth is available
.take(1)
.flatMap { _ in manager.scanForPeripherals(withServices: [CBUUID.Device.mainService])} // find peripheral
.filter { $0.peripheral.identifier == userRepository.getSavedBottle()}
.take(1)
.flatMap { $0.peripheral.establishConnection() } // connect to peripheral
.flatMap { $0.discoverServices([CBUUID.Device.mainService]) } // discover services
.flatMap { Observable.from($0) }
.flatMap { $0.discoverCharacteristics([CBUUID.Device.readUUID, CBUUID.Device.writeUUID]) } // discover characteristics
.flatMap { characteristics -> Observable<(read: Characteristic, write: Characteristic)> in
// find read and write characteristics
let readCharacteristic = characteristics.first(where: { $0.uuid == CBUUID.Device.readUUID})
let writeCharacteristic = characteristics.first(where: { $0.uuid == CBUUID.Device.writeUUID})
// if characteristics were not found emit an error
guard let unwrappedReadCharacteristic = readCharacteristic,
let unwrappedWriteCharacteristic = writeCharacteristic else {
return .error(Error.characteristicsNotFound)
}
// start observing read characteristic and map result value to pass both read and write characteristic to the next block
return unwrappedReadCharacteristic.observeValueUpdateAndSetNotification()
.map { (read: $0, write: unwrappedWriteCharacteristic) }
}
.flatMap { characteristisc -> Single<Characteristic> in
// read value from read characteristic
let value = characteristisc.read.value?.withUnsafeBytes({(rawPtr: UnsafeRawBufferPointer) in
return rawPtr.load(as: UInt64.self)
})
print(value)
// after reading value, write new data to write characteristic
return characteristisc.write.writeValue(Data(), type: .withResponse)
}
.subscribe(onNext: { _ in
print("Write operation finished.")
})
.disposed(by: disposeBag)
I hope that this will help you.
eddy93 commented
Thanks that’s very helpful! Any idea how I can do it if I want to continuously:
Write then read, write then read...