Skip to content

Commit 0dd8cab

Browse files
Merge pull request #286 from Polidea/fix/canSendWriteWithoutResponseCheck
fixes Characteristic writeWithoutResponse request does not return #282
2 parents 217b2e3 + bd9f3de commit 0dd8cab

File tree

5 files changed

+33
-10
lines changed

5 files changed

+33
-10
lines changed

Cartfile.resolved

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
github "ReactiveX/RxSwift" "4.2.0"
1+
github "ReactiveX/RxSwift" "4.3.0"

Source/Peripheral.swift

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -411,7 +411,8 @@ public class Peripheral {
411411
/// - parameter data: Data that'll be written to `Characteristic` instance
412412
/// - parameter characteristic: `Characteristic` instance to write value to.
413413
/// - parameter type: Type of write operation. Possible values: `.withResponse`, `.withoutResponse`
414-
/// - returns: Observable that emition depends on `CBCharacteristicWriteType` passed to the function call.
414+
/// - parameter canSendWriteWithoutResponseCheckEnabled: check if canSendWriteWithoutResponse should be enabled. Done because of internal MacOS bug.
415+
/// - returns: Observable that emission depends on `CBCharacteristicWriteType` passed to the function call.
415416
///
416417
/// Observable can ends with following errors:
417418
/// * `BluetoothError.characteristicWriteFailed`
@@ -424,7 +425,8 @@ public class Peripheral {
424425
/// * `BluetoothError.bluetoothResetting`
425426
public func writeValue(_ data: Data,
426427
for characteristic: Characteristic,
427-
type: CBCharacteristicWriteType) -> Single<Characteristic> {
428+
type: CBCharacteristicWriteType,
429+
canSendWriteWithoutResponseCheckEnabled: Bool = true) -> Single<Characteristic> {
428430
let writeOperationPerformingAndListeningObservable = { [weak self] (observable: Observable<Characteristic>)
429431
-> Observable<Characteristic> in
430432
guard let strongSelf = self else { return Observable.error(BluetoothError.destroyed) }
@@ -442,7 +444,7 @@ public class Peripheral {
442444
guard let strongSelf = self else { throw BluetoothError.destroyed }
443445
return strongSelf.observeWriteWithoutResponseReadiness()
444446
.map { _ in true }
445-
.startWith(strongSelf.canSendWriteWithoutResponse)
447+
.startWith(canSendWriteWithoutResponseCheckEnabled ? strongSelf.canSendWriteWithoutResponse : true)
446448
.filter { $0 }
447449
.take(1)
448450
.flatMap { _ in

Tests/Autogenerated/_Peripheral.generated.swift

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -412,7 +412,8 @@ class _Peripheral {
412412
/// - parameter data: Data that'll be written to `_Characteristic` instance
413413
/// - parameter characteristic: `_Characteristic` instance to write value to.
414414
/// - parameter type: Type of write operation. Possible values: `.withResponse`, `.withoutResponse`
415-
/// - returns: Observable that emition depends on `CBCharacteristicWriteType` passed to the function call.
415+
/// - parameter canSendWriteWithoutResponseCheckEnabled: check if canSendWriteWithoutResponse should be enabled. Done because of internal MacOS bug.
416+
/// - returns: Observable that emission depends on `CBCharacteristicWriteType` passed to the function call.
416417
///
417418
/// Observable can ends with following errors:
418419
/// * `_BluetoothError.characteristicWriteFailed`
@@ -425,7 +426,8 @@ class _Peripheral {
425426
/// * `_BluetoothError.bluetoothResetting`
426427
func writeValue(_ data: Data,
427428
for characteristic: _Characteristic,
428-
type: CBCharacteristicWriteType) -> Single<_Characteristic> {
429+
type: CBCharacteristicWriteType,
430+
canSendWriteWithoutResponseCheckEnabled: Bool = true) -> Single<_Characteristic> {
429431
let writeOperationPerformingAndListeningObservable = { [weak self] (observable: Observable<_Characteristic>)
430432
-> Observable<_Characteristic> in
431433
guard let strongSelf = self else { return Observable.error(_BluetoothError.destroyed) }
@@ -443,7 +445,7 @@ class _Peripheral {
443445
guard let strongSelf = self else { throw _BluetoothError.destroyed }
444446
return strongSelf.observeWriteWithoutResponseReadiness()
445447
.map { _ in true }
446-
.startWith(strongSelf.canSendWriteWithoutResponse)
448+
.startWith( canSendWriteWithoutResponseCheckEnabled ? strongSelf.canSendWriteWithoutResponse : true)
447449
.filter { $0 }
448450
.take(1)
449451
.flatMap { _ in

Tests/PeripheralTest+CharacteristicOperation.swift

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -105,6 +105,25 @@ class PeripheralCharacteristicOperationsTest: BasePeripheralTest {
105105
XCTAssertEqual(obs.events[0].value.element, characteristic, "should receive next events with characteristic")
106106
XCTAssertTrue(obs.events[1].value == .completed, "should receive completed event")
107107
}
108+
109+
func testWriteValueWithoutResponseWithCanSendWriteWithoutResponseCheckDisabled() {
110+
let characteristic = _Characteristic(characteristic: createCharacteristic(uuid: "0x0001", service: service), peripheral: peripheral)
111+
let data = Data(bytes: [0, 1, 2, 3])
112+
peripheral.peripheral.canSendWriteWithoutResponse = false
113+
114+
let obs: ScheduledObservable<_Characteristic> = testScheduler.scheduleObservable {
115+
self.peripheral.writeValue(data, for: characteristic, type: .withoutResponse, canSendWriteWithoutResponseCheckEnabled: false).asObservable()
116+
}
117+
118+
testScheduler.advanceTo(subscribeTime)
119+
120+
XCTAssertEqual(peripheral.peripheral.writeValueWithTypeParams.count, 1, "should call writeValueWithType method for the peripheral")
121+
let params = peripheral.peripheral.writeValueWithTypeParams[0]
122+
XCTAssertTrue(params.0 == data && params.1 == characteristic.characteristic && params.2 == .withoutResponse, "should call writeValueWithType with correct parameters")
123+
XCTAssertEqual(obs.events.count, 2, "should not receive two events immediately after subscription")
124+
XCTAssertEqual(obs.events[0].value.element, characteristic, "should receive next events with characteristic")
125+
XCTAssertTrue(obs.events[1].value == .completed, "should receive completed event")
126+
}
108127

109128
func testWriteValueWithoutResponseWaitingOnReadiness() {
110129
let characteristic = _Characteristic(characteristic: createCharacteristic(uuid: "0x0001", service: service), peripheral: peripheral)

scripts/generate-mocks.sh

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -27,10 +27,10 @@ fi
2727
IOS_VERSION="$1"
2828

2929
if [ -z "$IOS_VERSION" ]; then
30-
echo "Please specify ios version to compile (default 11.1):"
30+
echo "Please specify ios version to compile (default 11.4):"
3131
read IOS_VERSION
3232
if [ -z "$IOS_VERSION" ]; then
33-
IOS_VERSION="11.1"
33+
IOS_VERSION="11.4"
3434
fi
3535
fi
3636

@@ -93,4 +93,4 @@ create_intermediate_source_file "CoreBluetooth.CBCentral"
9393
sourcery --sources ./Intermediates --sources ../Source --templates ../Templates --output ../Tests/Autogenerated
9494

9595
rm temp.yml
96-
rm -rf ./Intermediates
96+
rm -rf ./Intermediates

0 commit comments

Comments
 (0)