Skip to content

Commit

Permalink
chore: iOS 15 support (#1)
Browse files Browse the repository at this point in the history
* Fixed deprecated methods by replacing the with new method signatures (fixed warning)

* Fixed warning `ManagerType` deprecated protocol class type

* Support for iOS 15

There are some changes to the CoreBluetooth API. Specially to the memory managment
Details are described here
Polidea#398

* Revert "Fixed deprecated methods by replacing the with new method signatures (fixed warning)"

This reverts commit e02bb01.

* Replace unnecessary chaining sequence of .map with compactMap

* Change force unrwapping in XCTest Classes to XCTUnwrap

---------

Co-authored-by: Chamira Fernando <[email protected]>
  • Loading branch information
86 and chamira-at authored Sep 26, 2023
1 parent 2a95bce commit 158c4ab
Show file tree
Hide file tree
Showing 14 changed files with 85 additions and 62 deletions.
7 changes: 5 additions & 2 deletions Source/CentralManagerRestoredState.swift
Original file line number Diff line number Diff line change
Expand Up @@ -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)
}
}
}
7 changes: 5 additions & 2 deletions Source/Characteristic.swift
Original file line number Diff line number Diff line change
Expand Up @@ -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)
}

Expand Down
11 changes: 8 additions & 3 deletions Source/Descriptor.swift
Original file line number Diff line number Diff line change
Expand Up @@ -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)
}

Expand Down
2 changes: 1 addition & 1 deletion Source/ManagerType.swift
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import Foundation
import RxSwift
import CoreBluetooth

public protocol ManagerType: class {
public protocol ManagerType: AnyObject {
associatedtype Manager

/// Implementation of CBManager
Expand Down
21 changes: 11 additions & 10 deletions Source/Peripheral.swift
Original file line number Diff line number Diff line change
Expand Up @@ -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)
}
Expand Down Expand Up @@ -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)
}
Expand Down Expand Up @@ -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)
}
Expand Down Expand Up @@ -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)
}
Expand Down Expand Up @@ -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)
}
Expand Down
13 changes: 6 additions & 7 deletions Tests/Autogenerated/Mock.generated.swift
Original file line number Diff line number Diff line change
@@ -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
Expand Down Expand Up @@ -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() {
}
Expand Down Expand Up @@ -263,7 +262,7 @@ class CBPeripheralMock: CBPeerMock {

}
class CBDescriptorMock: CBAttributeMock {
var characteristic: CBCharacteristicMock!
var characteristic: CBCharacteristicMock?
var value: Any?
var logDescription: String!

Expand All @@ -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]?
Expand All @@ -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]?
Expand Down Expand Up @@ -326,8 +325,8 @@ class CBATTRequestMock: NSObject {
}
class CBCentralMock: CBPeerMock {
var maximumUpdateValueLength: Int!
var logDescription: String!
var uuidIdentifier: UUID!
var logDescription: String!

override init() {
}
Expand Down
2 changes: 1 addition & 1 deletion Tests/Autogenerated/_CentralManager.generated.swift
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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)
}
}
}
7 changes: 5 additions & 2 deletions Tests/Autogenerated/_Characteristic.generated.swift
Original file line number Diff line number Diff line change
Expand Up @@ -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)
}

Expand Down
11 changes: 8 additions & 3 deletions Tests/Autogenerated/_Descriptor.generated.swift
Original file line number Diff line number Diff line change
Expand Up @@ -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)
}

Expand Down
2 changes: 1 addition & 1 deletion Tests/Autogenerated/_ManagerType.generated.swift
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import RxSwift
import CoreBluetooth
@testable import RxBluetoothKit

protocol _ManagerType: class {
protocol _ManagerType: AnyObject {
associatedtype Manager

/// Implementation of CBManagerMock
Expand Down
21 changes: 11 additions & 10 deletions Tests/Autogenerated/_Peripheral.generated.swift
Original file line number Diff line number Diff line change
Expand Up @@ -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)
}
Expand Down Expand Up @@ -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)
}
Expand Down Expand Up @@ -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)
}
Expand Down Expand Up @@ -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)
}
Expand Down Expand Up @@ -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)
}
Expand Down
28 changes: 14 additions & 14 deletions Tests/PeripheralTest+CharacteristicOperation.swift
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand All @@ -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

Expand All @@ -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

Expand All @@ -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

Expand Down Expand Up @@ -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)
Expand All @@ -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()
Expand All @@ -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()
Expand Down
Loading

0 comments on commit 158c4ab

Please sign in to comment.