diff --git a/Source/CentralManagerRestoredState.swift b/Source/CentralManagerRestoredState.swift index 81d6e62c..9287a240 100644 --- a/Source/CentralManagerRestoredState.swift +++ b/Source/CentralManagerRestoredState.swift @@ -60,7 +60,10 @@ public struct CentralManagerRestoredState: CentralManagerRestoredStateType { let cbServices = arrayOfAnyObjects.flatMap { $0 as? CBService } #endif - return cbServices.map { Service(peripheral: centralManager.retrievePeripheral(for: $0.peripheral), - service: $0) } + return cbServices.compactMap { + guard let cbPeripheral = $0.peripheral else { return nil } + let peripheral = centralManager.retrievePeripheral(for: cbPeripheral) + return Service(peripheral: peripheral, service: $0) + } } } diff --git a/Source/Characteristic.swift b/Source/Characteristic.swift index f4f2edec..9343e7ef 100644 --- a/Source/Characteristic.swift +++ b/Source/Characteristic.swift @@ -40,8 +40,11 @@ public class Characteristic { self.service = service } - convenience init(characteristic: CBCharacteristic, peripheral: Peripheral) { - let service = Service(peripheral: peripheral, service: characteristic.service) + convenience init?(characteristic: CBCharacteristic, peripheral: Peripheral) { + guard let _service = characteristic.service else { + return nil + } + let service = Service(peripheral: peripheral, service: _service) self.init(characteristic: characteristic, service: service) } diff --git a/Source/Descriptor.swift b/Source/Descriptor.swift index dff8f3f3..db5556e5 100644 --- a/Source/Descriptor.swift +++ b/Source/Descriptor.swift @@ -28,9 +28,14 @@ public class Descriptor { self.characteristic = characteristic } - convenience init(descriptor: CBDescriptor, peripheral: Peripheral) { - let service = Service(peripheral: peripheral, service: descriptor.characteristic.service) - let characteristic = Characteristic(characteristic: descriptor.characteristic, service: service) + convenience init?(descriptor: CBDescriptor, peripheral: Peripheral) { + + guard let _characteristic = descriptor.characteristic, let _service = _characteristic.service else { + return nil + } + + let service = Service(peripheral: peripheral, service: _service) + let characteristic = Characteristic(characteristic: _characteristic, service: service) self.init(descriptor: descriptor, characteristic: characteristic) } diff --git a/Source/ManagerType.swift b/Source/ManagerType.swift index b99481b0..4528dd91 100644 --- a/Source/ManagerType.swift +++ b/Source/ManagerType.swift @@ -2,7 +2,7 @@ import Foundation import RxSwift import CoreBluetooth -public protocol ManagerType: class { +public protocol ManagerType: AnyObject { associatedtype Manager /// Implementation of CBManager diff --git a/Source/Peripheral.swift b/Source/Peripheral.swift index 9a783c74..8297637e 100644 --- a/Source/Peripheral.swift +++ b/Source/Peripheral.swift @@ -401,8 +401,9 @@ public class Peripheral { .peripheralDidWriteValueForCharacteristic .filter { characteristic != nil ? ($0.0 == characteristic!.characteristic) : true } .map { [weak self] (cbCharacteristic, error) -> Characteristic in - guard let strongSelf = self else { throw BluetoothError.destroyed } - let characteristic = characteristic ?? Characteristic(characteristic: cbCharacteristic, peripheral: strongSelf) + guard let strongSelf = self, + let characteristic = characteristic ?? Characteristic(characteristic: cbCharacteristic, peripheral: strongSelf) else { throw BluetoothError.destroyed } + if let error = error { throw BluetoothError.characteristicWriteFailed(characteristic, error) } @@ -497,8 +498,8 @@ public class Peripheral { .peripheralDidUpdateValueForCharacteristic .filter { characteristic != nil ? ($0.0 == characteristic!.characteristic) : true } .map { [weak self] (cbCharacteristic, error) -> Characteristic in - guard let strongSelf = self else { throw BluetoothError.destroyed } - let characteristic = characteristic ?? Characteristic(characteristic: cbCharacteristic, peripheral: strongSelf) + guard let strongSelf = self, let characteristic = characteristic ?? Characteristic(characteristic: cbCharacteristic, peripheral: strongSelf) else { throw BluetoothError.destroyed } + if let error = error { throw BluetoothError.characteristicReadFailed(characteristic, error) } @@ -567,8 +568,9 @@ public class Peripheral { return delegateWrapper.peripheralDidUpdateNotificationStateForCharacteristic .filter { $0.0 == characteristic.characteristic } .map { [weak self] (cbCharacteristic, error) -> Characteristic in - guard let strongSelf = self else { throw BluetoothError.destroyed } - let characteristic = Characteristic(characteristic: cbCharacteristic, peripheral: strongSelf) + guard let strongSelf = self, + let characteristic = Characteristic(characteristic: cbCharacteristic, peripheral: strongSelf) else { throw BluetoothError.destroyed } + if let error = error { throw BluetoothError.characteristicSetNotifyValueFailed(characteristic, error) } @@ -636,8 +638,8 @@ public class Peripheral { .peripheralDidWriteValueForDescriptor .filter { descriptor != nil ? ($0.0 == descriptor!.descriptor) : true } .map { [weak self] (cbDescriptor, error) -> Descriptor in - guard let strongSelf = self else { throw BluetoothError.destroyed } - let descriptor = descriptor ?? Descriptor(descriptor: cbDescriptor, peripheral: strongSelf) + guard let strongSelf = self, let descriptor = descriptor ?? Descriptor(descriptor: cbDescriptor, peripheral: strongSelf) else { throw BluetoothError.destroyed } + if let error = error { throw BluetoothError.descriptorWriteFailed(descriptor, error) } @@ -665,8 +667,7 @@ public class Peripheral { .peripheralDidUpdateValueForDescriptor .filter { descriptor != nil ? ($0.0 == descriptor!.descriptor) : true } .map { [weak self] (cbDescriptor, error) -> Descriptor in - guard let strongSelf = self else { throw BluetoothError.destroyed } - let descriptor = descriptor ?? Descriptor(descriptor: cbDescriptor, peripheral: strongSelf) + guard let strongSelf = self, let descriptor = descriptor ?? Descriptor(descriptor: cbDescriptor, peripheral: strongSelf) else { throw BluetoothError.destroyed } if let error = error { throw BluetoothError.descriptorReadFailed(descriptor, error) } diff --git a/Tests/Autogenerated/Mock.generated.swift b/Tests/Autogenerated/Mock.generated.swift index 2bd7d33b..146f8570 100644 --- a/Tests/Autogenerated/Mock.generated.swift +++ b/Tests/Autogenerated/Mock.generated.swift @@ -1,6 +1,5 @@ -// Generated using Sourcery 1.0.0 — https://github.com/krzysztofzablocki/Sourcery +// Generated using Sourcery 1.1.0 — https://github.com/krzysztofzablocki/Sourcery // DO NOT EDIT - import CoreBluetooth @testable import RxBluetoothKit @@ -188,8 +187,8 @@ class CBPeripheralMock: CBPeerMock { var services: [CBServiceMock]? var canSendWriteWithoutResponse: Bool! var ancsAuthorized: Bool! - var logDescription: String! var uuidIdentifier: UUID! + var logDescription: String! override init() { } @@ -263,7 +262,7 @@ class CBPeripheralMock: CBPeerMock { } class CBDescriptorMock: CBAttributeMock { - var characteristic: CBCharacteristicMock! + var characteristic: CBCharacteristicMock? var value: Any? var logDescription: String! @@ -272,7 +271,7 @@ class CBDescriptorMock: CBAttributeMock { } class CBServiceMock: CBAttributeMock { - var peripheral: CBPeripheralMock! + var peripheral: CBPeripheralMock? var isPrimary: Bool! var includedServices: [CBServiceMock]? var characteristics: [CBCharacteristicMock]? @@ -283,7 +282,7 @@ class CBServiceMock: CBAttributeMock { } class CBCharacteristicMock: CBAttributeMock { - var service: CBServiceMock! + var service: CBServiceMock? var properties: CBCharacteristicProperties! var value: Data? var descriptors: [CBDescriptorMock]? @@ -326,8 +325,8 @@ class CBATTRequestMock: NSObject { } class CBCentralMock: CBPeerMock { var maximumUpdateValueLength: Int! - var logDescription: String! var uuidIdentifier: UUID! + var logDescription: String! override init() { } diff --git a/Tests/Autogenerated/_CentralManager.generated.swift b/Tests/Autogenerated/_CentralManager.generated.swift index 81e6aed5..6cd18f33 100644 --- a/Tests/Autogenerated/_CentralManager.generated.swift +++ b/Tests/Autogenerated/_CentralManager.generated.swift @@ -299,7 +299,7 @@ class _CentralManager: _ManagerType { return (peripheral, error) } return ensure(.poweredOn, observable: observable) - .catchError { error in + .catch { error in if error is _BluetoothError, let peripheral = peripheral { return .concat(.just((peripheral, error)), .error(error)) } else { diff --git a/Tests/Autogenerated/_CentralManagerRestoredState.generated.swift b/Tests/Autogenerated/_CentralManagerRestoredState.generated.swift index 2d1c93a6..aba905ca 100644 --- a/Tests/Autogenerated/_CentralManagerRestoredState.generated.swift +++ b/Tests/Autogenerated/_CentralManagerRestoredState.generated.swift @@ -61,7 +61,10 @@ struct _CentralManagerRestoredState: CentralManagerRestoredStateType { let cbServices = arrayOfAnyObjects.flatMap { $0 as? CBServiceMock } #endif - return cbServices.map { _Service(peripheral: centralManager.retrievePeripheral(for: $0.peripheral), - service: $0) } + return cbServices.compactMap { + guard let cbPeripheral = $0.peripheral else { return nil } + let peripheral = centralManager.retrievePeripheral(for: cbPeripheral) + return _Service(peripheral: peripheral, service: $0) + } } } diff --git a/Tests/Autogenerated/_Characteristic.generated.swift b/Tests/Autogenerated/_Characteristic.generated.swift index ea2eb42a..9617cd35 100644 --- a/Tests/Autogenerated/_Characteristic.generated.swift +++ b/Tests/Autogenerated/_Characteristic.generated.swift @@ -41,8 +41,11 @@ class _Characteristic { self.service = service } - convenience init(characteristic: CBCharacteristicMock, peripheral: _Peripheral) { - let service = _Service(peripheral: peripheral, service: characteristic.service) + convenience init?(characteristic: CBCharacteristicMock, peripheral: _Peripheral) { + guard let _service = characteristic.service else { + return nil + } + let service = _Service(peripheral: peripheral, service: _service) self.init(characteristic: characteristic, service: service) } diff --git a/Tests/Autogenerated/_Descriptor.generated.swift b/Tests/Autogenerated/_Descriptor.generated.swift index ca6b8c74..c40b47e2 100644 --- a/Tests/Autogenerated/_Descriptor.generated.swift +++ b/Tests/Autogenerated/_Descriptor.generated.swift @@ -29,9 +29,14 @@ class _Descriptor { self.characteristic = characteristic } - convenience init(descriptor: CBDescriptorMock, peripheral: _Peripheral) { - let service = _Service(peripheral: peripheral, service: descriptor.characteristic.service) - let characteristic = _Characteristic(characteristic: descriptor.characteristic, service: service) + convenience init?(descriptor: CBDescriptorMock, peripheral: _Peripheral) { + + guard let _characteristic = descriptor.characteristic, let _service = _characteristic.service else { + return nil + } + + let service = _Service(peripheral: peripheral, service: _service) + let characteristic = _Characteristic(characteristic: _characteristic, service: service) self.init(descriptor: descriptor, characteristic: characteristic) } diff --git a/Tests/Autogenerated/_ManagerType.generated.swift b/Tests/Autogenerated/_ManagerType.generated.swift index eb604dae..124c203f 100644 --- a/Tests/Autogenerated/_ManagerType.generated.swift +++ b/Tests/Autogenerated/_ManagerType.generated.swift @@ -3,7 +3,7 @@ import RxSwift import CoreBluetooth @testable import RxBluetoothKit -protocol _ManagerType: class { +protocol _ManagerType: AnyObject { associatedtype Manager /// Implementation of CBManagerMock diff --git a/Tests/Autogenerated/_Peripheral.generated.swift b/Tests/Autogenerated/_Peripheral.generated.swift index a295f858..d917fc59 100644 --- a/Tests/Autogenerated/_Peripheral.generated.swift +++ b/Tests/Autogenerated/_Peripheral.generated.swift @@ -402,8 +402,9 @@ class _Peripheral { .peripheralDidWriteValueForCharacteristic .filter { characteristic != nil ? ($0.0 == characteristic!.characteristic) : true } .map { [weak self] (cbCharacteristic, error) -> _Characteristic in - guard let strongSelf = self else { throw _BluetoothError.destroyed } - let characteristic = characteristic ?? _Characteristic(characteristic: cbCharacteristic, peripheral: strongSelf) + guard let strongSelf = self, + let characteristic = characteristic ?? _Characteristic(characteristic: cbCharacteristic, peripheral: strongSelf) else { throw _BluetoothError.destroyed } + if let error = error { throw _BluetoothError.characteristicWriteFailed(characteristic, error) } @@ -498,8 +499,8 @@ class _Peripheral { .peripheralDidUpdateValueForCharacteristic .filter { characteristic != nil ? ($0.0 == characteristic!.characteristic) : true } .map { [weak self] (cbCharacteristic, error) -> _Characteristic in - guard let strongSelf = self else { throw _BluetoothError.destroyed } - let characteristic = characteristic ?? _Characteristic(characteristic: cbCharacteristic, peripheral: strongSelf) + guard let strongSelf = self, let characteristic = characteristic ?? _Characteristic(characteristic: cbCharacteristic, peripheral: strongSelf) else { throw _BluetoothError.destroyed } + if let error = error { throw _BluetoothError.characteristicReadFailed(characteristic, error) } @@ -568,8 +569,9 @@ class _Peripheral { return delegateWrapper.peripheralDidUpdateNotificationStateForCharacteristic .filter { $0.0 == characteristic.characteristic } .map { [weak self] (cbCharacteristic, error) -> _Characteristic in - guard let strongSelf = self else { throw _BluetoothError.destroyed } - let characteristic = _Characteristic(characteristic: cbCharacteristic, peripheral: strongSelf) + guard let strongSelf = self, + let characteristic = _Characteristic(characteristic: cbCharacteristic, peripheral: strongSelf) else { throw _BluetoothError.destroyed } + if let error = error { throw _BluetoothError.characteristicSetNotifyValueFailed(characteristic, error) } @@ -637,8 +639,8 @@ class _Peripheral { .peripheralDidWriteValueForDescriptor .filter { descriptor != nil ? ($0.0 == descriptor!.descriptor) : true } .map { [weak self] (cbDescriptor, error) -> _Descriptor in - guard let strongSelf = self else { throw _BluetoothError.destroyed } - let descriptor = descriptor ?? _Descriptor(descriptor: cbDescriptor, peripheral: strongSelf) + guard let strongSelf = self, let descriptor = descriptor ?? _Descriptor(descriptor: cbDescriptor, peripheral: strongSelf) else { throw _BluetoothError.destroyed } + if let error = error { throw _BluetoothError.descriptorWriteFailed(descriptor, error) } @@ -666,8 +668,7 @@ class _Peripheral { .peripheralDidUpdateValueForDescriptor .filter { descriptor != nil ? ($0.0 == descriptor!.descriptor) : true } .map { [weak self] (cbDescriptor, error) -> _Descriptor in - guard let strongSelf = self else { throw _BluetoothError.destroyed } - let descriptor = descriptor ?? _Descriptor(descriptor: cbDescriptor, peripheral: strongSelf) + guard let strongSelf = self, let descriptor = descriptor ?? _Descriptor(descriptor: cbDescriptor, peripheral: strongSelf) else { throw _BluetoothError.destroyed } if let error = error { throw _BluetoothError.descriptorReadFailed(descriptor, error) } diff --git a/Tests/PeripheralTest+CharacteristicOperation.swift b/Tests/PeripheralTest+CharacteristicOperation.swift index 8003f563..afcbb911 100644 --- a/Tests/PeripheralTest+CharacteristicOperation.swift +++ b/Tests/PeripheralTest+CharacteristicOperation.swift @@ -61,8 +61,8 @@ class PeripheralCharacteristicOperationsTest: BasePeripheralTest { XCTAssertEqual(obs.events[0].value.element, characteristic, "should receive event for correct characteristic") } - func testWriteValueWithResponse() { - let characteristic = _Characteristic(characteristic: createCharacteristic(uuid: "0x0001", service: service), peripheral: peripheral) + func testWriteValueWithResponse() throws { + let characteristic = XCTUnwrap(_Characteristic(characteristic: createCharacteristic(uuid: "0x0001", service: service), peripheral: peripheral) let data = Data([0, 1, 2, 3]) let obs: ScheduledObservable<_Characteristic> = testScheduler.scheduleObservable { @@ -87,8 +87,8 @@ class PeripheralCharacteristicOperationsTest: BasePeripheralTest { XCTAssertTrue(obs.events[1].value == .completed, "should receive completed event") } - func testWriteValueWithoutResponse() { - let characteristic = _Characteristic(characteristic: createCharacteristic(uuid: "0x0001", service: service), peripheral: peripheral) + func testWriteValueWithoutResponse() throws { + let characteristic = XCTUnwrap(_Characteristic(characteristic: createCharacteristic(uuid: "0x0001", service: service), peripheral: peripheral)) let data = Data([0, 1, 2, 3]) peripheral.peripheral.canSendWriteWithoutResponse = true @@ -106,8 +106,8 @@ class PeripheralCharacteristicOperationsTest: BasePeripheralTest { XCTAssertTrue(obs.events[1].value == .completed, "should receive completed event") } - func testWriteValueWithoutResponseWithCanSendWriteWithoutResponseCheckDisabled() { - let characteristic = _Characteristic(characteristic: createCharacteristic(uuid: "0x0001", service: service), peripheral: peripheral) + func testWriteValueWithoutResponseWithCanSendWriteWithoutResponseCheckDisabled() throws { + let characteristic = XCTUnwrap(_Characteristic(characteristic: createCharacteristic(uuid: "0x0001", service: service), peripheral: peripheral)) let data = Data([0, 1, 2, 3]) peripheral.peripheral.canSendWriteWithoutResponse = false @@ -125,8 +125,8 @@ class PeripheralCharacteristicOperationsTest: BasePeripheralTest { XCTAssertTrue(obs.events[1].value == .completed, "should receive completed event") } - func testWriteValueWithoutResponseWaitingOnReadiness() { - let characteristic = _Characteristic(characteristic: createCharacteristic(uuid: "0x0001", service: service), peripheral: peripheral) + func testWriteValueWithoutResponseWaitingOnReadiness() throws{ + let characteristic = XCTUnwrap(_Characteristic(characteristic: createCharacteristic(uuid: "0x0001", service: service), peripheral: peripheral)) let data = Data([0, 1, 2, 3]) peripheral.peripheral.canSendWriteWithoutResponse = false @@ -198,9 +198,9 @@ class PeripheralCharacteristicOperationsTest: BasePeripheralTest { XCTAssertEqual(obs.events[0].value.element, characteristic, "should receive event for correct characteristic") } - func testObserveCharacteristicIsNotifyingValue() { + func testObserveCharacteristicIsNotifyingValue() throws { let mockCharacteristic = createCharacteristic(uuid: "0x0001", service: service) - let characteristic = _Characteristic(characteristic: mockCharacteristic, peripheral: peripheral) + let characteristic = XCTUnwrap(_Characteristic(characteristic: mockCharacteristic, peripheral: peripheral)) let obs: ScheduledObservable<_Characteristic> = testScheduler.scheduleObservable { self.peripheral.observeNotifyValue(for: characteristic) @@ -219,9 +219,9 @@ class PeripheralCharacteristicOperationsTest: BasePeripheralTest { XCTAssertEqual(obs.events[0].value.element, characteristic, "should receive event for correct characteristic") } - func testCharacteristicIsNotifyingValueChange() { + func testCharacteristicIsNotifyingValueChange() throws { let mockCharacteristic = createCharacteristic(uuid: "0x0001", service: service) - let characteristic = _Characteristic(characteristic: mockCharacteristic, peripheral: peripheral) + let characteristic = XCTUnwrap(_Characteristic(characteristic: mockCharacteristic, peripheral: peripheral)) let obs: ScheduledObservable<_Characteristic> = testScheduler.scheduleObservable { characteristic.observeNotifyValue() @@ -240,8 +240,8 @@ class PeripheralCharacteristicOperationsTest: BasePeripheralTest { XCTAssertEqual(obs.events[0].value.element, characteristic, "should receive event for correct characteristic") } - func testReadValue() { - let characteristic = _Characteristic(characteristic: createCharacteristic(uuid: "0x0001", service: service), peripheral: peripheral) + func testReadValue() throws { + let characteristic = XCTUnwrap(_Characteristic(characteristic: createCharacteristic(uuid: "0x0001", service: service), peripheral: peripheral)) let obs: ScheduledObservable<_Characteristic> = testScheduler.scheduleObservable { self.peripheral.readValue(for: characteristic).asObservable() diff --git a/Tests/PeripheralTest+DescriptorsOperation.swift b/Tests/PeripheralTest+DescriptorsOperation.swift index e73bb691..37105aaf 100644 --- a/Tests/PeripheralTest+DescriptorsOperation.swift +++ b/Tests/PeripheralTest+DescriptorsOperation.swift @@ -63,8 +63,8 @@ class PeripheralDescriptorOperationsTest: BasePeripheralTest { XCTAssertEqual(obs.events[0].value.element, descriptor, "should receive event for correct descriptor") } - func testWriteValue() { - let descriptor = _Descriptor(descriptor: createDescriptor(uuid: "0x0002", characteristic: characteristic), peripheral: peripheral) + func testWriteValue() throws { + let descriptor = XCTUnwrap(_Descriptor(descriptor: createDescriptor(uuid: "0x0002", characteristic: characteristic), peripheral: peripheral)) let data = Data([0, 1, 2, 3]) let obs: ScheduledObservable<_Descriptor> = testScheduler.scheduleObservable { @@ -135,8 +135,8 @@ class PeripheralDescriptorOperationsTest: BasePeripheralTest { XCTAssertEqual(obs.events[0].value.element, descriptor, "should receive event for correct descriptor") } - func testReadValue() { - let descriptor = _Descriptor(descriptor: createDescriptor(uuid: "0x0001", characteristic: characteristic), peripheral: peripheral) + func testReadValue() throws { + let descriptor = XCTUnwrap(_Descriptor(descriptor: createDescriptor(uuid: "0x0001", characteristic: characteristic), peripheral: peripheral)) let obs: ScheduledObservable<_Descriptor> = testScheduler.scheduleObservable { self.peripheral.readValue(for: descriptor).asObservable()