Files
bluetooth_low_energy/bluetooth_low_energy_darwin/darwin/Classes/MyCentralManager.swift
iAMD 87fe3e2447 feat: 5.0.0 (#35)
* draft: 临时提交

* feat: 实现扫描功能

* fix: 优化广播逻辑

* feat: 添加协程方法

* fix: 修改宏定义

* draft: 临时提交

* feat: 调整接口

* fix: 修改版本号

* feat: 4.1.1

* draft: 临时提交

* feat: 5.0.0-dev.2

* fix: 修复版本号错误

* draft: 临时提交

* fix: 修复连接断开异常

* fix: 修复问题

* fix: 优化代码

* fix:  优化 short UUID 格式化逻辑

* fix: 尝试实现 read_rssi 接口,当前此接口不可用,会报异常

* feat: 删除 getMaximumWriteLength 方法

* fix: 更新 CHANGELOG.md

* feat: 5.0.0-dev.1

* fix: 更新依赖项

* feat: linux-5.0.0-dev.1

* fix: 更新 CHANGELOG.md

* fix: 开始搜索设备时清空设备列表

* fix: 开始扫描时清空设备列表

* feat: 5.0.0-dev.2

* fix: 优化 MyGattService 和 MyGattCharacteristic

* feat: 更新 interface 版本 -> 5.0.0-dev.4

* feat: 更新 interface 版本 -> 5.0.0-dev.4

* feat: 实现 flutter 部分 5.0.0

* fix: 移除 maximumWriteLength

* fix: 移除 rssi

* feat: 5.0.0-dev.1

* feat: 5.0.0-dev.2

* fix: 更新依赖项

* fix: 5.0.0-dev.4

* fix: 更新依赖项

* draft: 临时提交

* feat: 5.0.0-dev.5

* draft: 删除 MyCentralManager 和 MyPeripheralManager

* fix: 更新依赖项

* fix: 更新依赖项

* feat: 适配新接口

* feat: 5.0.0-dev.6

* draft: 临时提交

* feat: 5.0.0-dev.7

* fix: 修改版本号

* feat: 5.0.0-dev.8

* feat: 5.0.0-dev.9

* fix: 修复 trimGATT 错误

* feat: 5.0.0-dev.6

* feat: 5.0.0-dev.3

* feat: 5.0.0-dev.4

* fix: 更新 pubspec.lock

* feat: 5.0.0-dev.7

* feat: 5.0.0-dev.3

* fix: balabala

* fix: balabala

* draft: 5.0.0-dev.1

* fix: trim GATT when call the `writeCharacteristic` method.

* fix: make difference of `trim` and `fragment`.

* feat: 5.0.0-dev.1

* feat: 5.0.0-dev.1

* feat: 优化示例程序

* fix: 更新 README.md

* fix: 修复插件引用

* draft: XXXX

* feat: 增加调试信息

* fix: 更新 pubspec.lock

* feat: 5.0.0-dev.4

* feat: 5.0.0-dev.3

* feat: 5.0.0

* feat: 5.0.0

* feat: 5.0.0

* feat: 5.0.0

* feat: 5.0.0

* feat: 5.0.0
2023-12-31 00:53:48 +08:00

633 lines
26 KiB
Swift

//
// MyCentralController.swift
// bluetooth_low_energy_ios
//
// Created by on 2023/8/13.
//
import Foundation
import CoreBluetooth
#if os(iOS)
import Flutter
#elseif os(macOS)
import FlutterMacOS
#else
#error("Unsupported platform.")
#endif
class MyCentralManager: MyCentralManagerHostApi {
private let _api: MyCentralManagerFlutterApi
private let _centralManager: CBCentralManager
private lazy var _centralManagerDelegate = MyCentralManagerDelegate(centralManager: self)
private lazy var _peripheralDelegate = MyPeripheralDelegate(centralManager: self)
private var _peripherals: [String: CBPeripheral]
private var _services: [String: [Int64: CBService]]
private var _characteristics: [String: [Int64: CBCharacteristic]]
private var _descriptors: [String: [Int64: CBDescriptor]]
private var _connectCompletions: [String: (Result<Void, Error>) -> Void]
private var _disconnectCompletions: [String: (Result<Void, Error>) -> Void]
private var _readRssiCompletions: [String: (Result<Int64, Error>) -> Void]
private var _discoverServicesCompletions: [String: (Result<[MyGattServiceArgs], Error>) -> Void]
private var _discoverCharacteristicsCompletions: [String: [Int64: (Result<[MyGattCharacteristicArgs], Error>) -> Void]]
private var _discoverDescriptorsCompletions: [String: [Int64: (Result<[MyGattDescriptorArgs], Error>) -> Void]]
private var _readCharacteristicCompletions: [String: [Int64: (Result<FlutterStandardTypedData, Error>) -> Void]]
private var _writeCharacteristicCompletions: [String: [Int64: (Result<Void, Error>) -> Void]]
private var _setCharacteristicNotifyStateCompletions: [String: [Int64: (Result<Void, Error>) -> Void]]
private var _readDescriptorCompletions: [String: [Int64: (Result<FlutterStandardTypedData, Error>) -> Void]]
private var _writeDescriptorCompletions: [String: [Int64: (Result<Void, Error>) -> Void]]
init(messenger: FlutterBinaryMessenger) {
_api = MyCentralManagerFlutterApi(binaryMessenger: messenger)
_centralManager = CBCentralManager()
_peripherals = [:]
_services = [:]
_characteristics = [:]
_descriptors = [:]
_connectCompletions = [:]
_disconnectCompletions = [:]
_readRssiCompletions = [:]
_discoverServicesCompletions = [:]
_discoverCharacteristicsCompletions = [:]
_discoverDescriptorsCompletions = [:]
_readCharacteristicCompletions = [:]
_writeCharacteristicCompletions = [:]
_setCharacteristicNotifyStateCompletions = [:]
_readDescriptorCompletions = [:]
_writeDescriptorCompletions = [:]
}
func setUp() throws {
_clearState()
if _centralManager.delegate == nil {
_centralManager.delegate = _centralManagerDelegate
}
_onStateChanged()
}
func startDiscovery() throws {
let options = [CBCentralManagerScanOptionAllowDuplicatesKey: true]
_centralManager.scanForPeripherals(withServices: nil, options: options)
}
func stopDiscovery() throws {
_centralManager.stopScan()
}
func connect(uuidArgs: String, completion: @escaping (Result<Void, Error>) -> Void) {
do {
guard let peripheral = _peripherals[uuidArgs] else {
throw MyError.illegalArgument
}
_centralManager.connect(peripheral)
_connectCompletions[uuidArgs] = completion
} catch {
completion(.failure(error))
}
}
func disconnect(uuidArgs: String, completion: @escaping (Result<Void, Error>) -> Void) {
do {
guard let peripheral = _peripherals[uuidArgs] else {
throw MyError.illegalArgument
}
_centralManager.cancelPeripheralConnection(peripheral)
_disconnectCompletions[uuidArgs] = completion
} catch {
completion(.failure(error))
}
}
func getMaximumWriteValueLength(uuidArgs: String, typeNumberArgs: Int64) throws -> Int64 {
guard let peripheral = _peripherals[uuidArgs] else {
throw MyError.illegalArgument
}
let typeNumber = typeNumberArgs.toInt()
guard let typeArgs = MyGattCharacteristicWriteTypeArgs(rawValue: typeNumber) else {
throw MyError.illegalArgument
}
let type = typeArgs.toWriteType()
let maximumWriteValueLength = peripheral.maximumWriteValueLength(for: type)
let maximumWriteValueLengthArgs = maximumWriteValueLength.toInt64()
return maximumWriteValueLengthArgs
}
func readRSSI(uuidArgs: String, completion: @escaping (Result<Int64, Error>) -> Void) {
do {
guard let peripheral = _peripherals[uuidArgs] else {
throw MyError.illegalArgument
}
peripheral.readRSSI()
_readRssiCompletions[uuidArgs] = completion
} catch {
completion(.failure(error))
}
}
func discoverServices(uuidArgs: String, completion: @escaping (Result<[MyGattServiceArgs], Error>) -> Void) {
do {
guard let peripheral = _peripherals[uuidArgs] else {
throw MyError.illegalArgument
}
peripheral.discoverServices(nil)
_discoverServicesCompletions[uuidArgs] = completion
} catch {
completion(.failure(error))
}
}
func discoverCharacteristics(uuidArgs: String, hashCodeArgs: Int64, completion: @escaping (Result<[MyGattCharacteristicArgs], Error>) -> Void) {
do {
guard let peripheral = _peripherals[uuidArgs] else {
throw MyError.illegalArgument
}
guard let service = _retrieveService(uuidArgs: uuidArgs, hashCodeArgs: hashCodeArgs) else {
throw MyError.illegalArgument
}
peripheral.discoverCharacteristics(nil, for: service)
_discoverCharacteristicsCompletions[uuidArgs, default: [:]][hashCodeArgs] = completion
} catch {
completion(.failure(error))
}
}
func discoverDescriptors(uuidArgs: String, hashCodeArgs: Int64, completion: @escaping (Result<[MyGattDescriptorArgs], Error>) -> Void){
do {
guard let peripheral = _peripherals[uuidArgs] else {
throw MyError.illegalArgument
}
guard let characteristic = _retrieveCharacteristic(uuidArgs: uuidArgs, hashCodeArgs: hashCodeArgs) else {
throw MyError.illegalArgument
}
peripheral.discoverDescriptors(for: characteristic)
_discoverDescriptorsCompletions[uuidArgs, default: [:]][hashCodeArgs] = completion
} catch {
completion(.failure(error))
}
}
func readCharacteristic(uuidArgs: String, hashCodeArgs: Int64, completion: @escaping (Result<FlutterStandardTypedData, Error>) -> Void) {
do {
guard let peripheral = _peripherals[uuidArgs] else {
throw MyError.illegalArgument
}
guard let characteristic = _retrieveCharacteristic(uuidArgs: uuidArgs, hashCodeArgs: hashCodeArgs) else {
throw MyError.illegalArgument
}
peripheral.readValue(for: characteristic)
_readCharacteristicCompletions[uuidArgs, default: [:]][hashCodeArgs] = completion
} catch {
completion(.failure(error))
}
}
func writeCharacteristic(uuidArgs: String, hashCodeArgs: Int64, valueArgs: FlutterStandardTypedData, typeNumberArgs: Int64, completion: @escaping (Result<Void, Error>) -> Void) {
do {
guard let peripheral = _peripherals[uuidArgs] else {
throw MyError.illegalArgument
}
guard let characteristic = _retrieveCharacteristic(uuidArgs: uuidArgs, hashCodeArgs: hashCodeArgs) else {
throw MyError.illegalArgument
}
let data = valueArgs.data
let typeNumber = typeNumberArgs.toInt()
guard let typeArgs = MyGattCharacteristicWriteTypeArgs(rawValue: typeNumber) else {
throw MyError.illegalArgument
}
let type = typeArgs.toWriteType()
peripheral.writeValue(data, for: characteristic, type: type)
if type == .withResponse {
_writeCharacteristicCompletions[uuidArgs, default: [:]][hashCodeArgs] = completion
} else {
completion(.success(()))
}
} catch {
completion(.failure(error))
}
}
func setCharacteristicNotifyState(uuidArgs: String, hashCodeArgs: Int64, stateArgs: Bool, completion: @escaping (Result<Void, Error>) -> Void) {
do {
guard let peripheral = _peripherals[uuidArgs] else {
throw MyError.illegalArgument
}
guard let characteristic = _retrieveCharacteristic(uuidArgs: uuidArgs, hashCodeArgs: hashCodeArgs) else {
throw MyError.illegalArgument
}
let enabled = stateArgs
peripheral.setNotifyValue(enabled, for: characteristic)
_setCharacteristicNotifyStateCompletions[uuidArgs, default: [:]][hashCodeArgs] = completion
} catch {
completion(.failure(error))
}
}
func readDescriptor(uuidArgs: String, hashCodeArgs: Int64, completion: @escaping (Result<FlutterStandardTypedData, Error>) -> Void) {
do {
guard let peripheral = _peripherals[uuidArgs] else {
throw MyError.illegalArgument
}
guard let descriptor = _retrieveDescriptor(uuidArgs: uuidArgs, hashCodeArgs: hashCodeArgs) else {
throw MyError.illegalArgument
}
peripheral.readValue(for: descriptor)
_readDescriptorCompletions[uuidArgs, default: [:]][hashCodeArgs] = completion
} catch {
completion(.failure(error))
}
}
func writeDescriptor(uuidArgs: String, hashCodeArgs: Int64, valueArgs: FlutterStandardTypedData, completion: @escaping (Result<Void, Error>) -> Void) {
do {
guard let peripheral = _peripherals[uuidArgs] else {
throw MyError.illegalArgument
}
guard let descriptor = _retrieveDescriptor(uuidArgs: uuidArgs, hashCodeArgs: hashCodeArgs) else {
throw MyError.illegalArgument
}
let data = valueArgs.data
peripheral.writeValue(data, for: descriptor)
_writeDescriptorCompletions[uuidArgs, default: [:]][hashCodeArgs] = completion
} catch {
completion(.failure(error))
}
}
func didUpdateState(central: CBCentralManager) {
_onStateChanged()
}
func didDiscover(central: CBCentralManager, peripheral: CBPeripheral, advertisementData: [String : Any], rssi: NSNumber) {
let peripheralArgs = peripheral.toArgs()
let uuidArgs = peripheralArgs.uuidArgs
let rssiArgs = rssi.int64Value
let advertisementArgs = advertisementData.toAdvertisementArgs()
if peripheral.delegate == nil {
peripheral.delegate = _peripheralDelegate
}
_peripherals[uuidArgs] = peripheral
_api.onDiscovered(peripheralArgs: peripheralArgs, rssiArgs: rssiArgs, advertisementArgs: advertisementArgs) {_ in }
}
func didConnect(central: CBCentralManager, peripheral: CBPeripheral) {
let uuidArgs = peripheral.identifier.toArgs()
let stateArgs = true
_api.onConnectionStateChanged(uuidArgs: uuidArgs, stateArgs: stateArgs) {_ in }
guard let completion = _connectCompletions.removeValue(forKey: uuidArgs) else {
return
}
completion(.success(()))
}
func didFailToConnect(central: CBCentralManager, peripheral: CBPeripheral, error: Error?) {
let uuidArgs = peripheral.identifier.toArgs()
guard let completion = _connectCompletions.removeValue(forKey: uuidArgs) else {
return
}
completion(.failure(error ?? MyError.unknown))
}
func didDisconnectPeripheral(central: CBCentralManager, peripheral: CBPeripheral, error: Error?) {
let uuidArgs = peripheral.identifier.toArgs()
_services.removeValue(forKey: uuidArgs)
_characteristics.removeValue(forKey: uuidArgs)
_descriptors.removeValue(forKey: uuidArgs)
let errorNotNil = error ?? MyError.unknown
let readRssiCompletion = _readRssiCompletions.removeValue(forKey: uuidArgs)
readRssiCompletion?(.failure(errorNotNil))
let discoverServicesCompletion = _discoverServicesCompletions.removeValue(forKey: uuidArgs)
discoverServicesCompletion?(.failure(errorNotNil))
let discoverCharacteristicsCompletions = _discoverCharacteristicsCompletions.removeValue(forKey: uuidArgs)
if discoverCharacteristicsCompletions != nil {
let completions = discoverCharacteristicsCompletions!.values
for completion in completions {
completion(.failure(errorNotNil))
}
}
let discoverDescriptorsCompletions = _discoverDescriptorsCompletions.removeValue(forKey: uuidArgs)
if discoverDescriptorsCompletions != nil {
let completions = discoverDescriptorsCompletions!.values
for completion in completions {
completion(.failure(errorNotNil))
}
}
let readCharacteristicCompletions = _readCharacteristicCompletions.removeValue(forKey: uuidArgs)
if readCharacteristicCompletions != nil {
let completions = readCharacteristicCompletions!.values
for completion in completions {
completion(.failure(errorNotNil))
}
}
let writeCharacteristicCompletions = _writeCharacteristicCompletions.removeValue(forKey: uuidArgs)
if writeCharacteristicCompletions != nil {
let completions = writeCharacteristicCompletions!.values
for completion in completions {
completion(.failure(errorNotNil))
}
}
let notifyCharacteristicCompletions = _setCharacteristicNotifyStateCompletions.removeValue(forKey: uuidArgs)
if notifyCharacteristicCompletions != nil {
let completions = notifyCharacteristicCompletions!.values
for completioin in completions {
completioin(.failure(errorNotNil))
}
}
let readDescriptorCompletions = _readDescriptorCompletions.removeValue(forKey: uuidArgs)
if readDescriptorCompletions != nil {
let completions = readDescriptorCompletions!.values
for completioin in completions {
completioin(.failure(errorNotNil))
}
}
let writeDescriptorCompletions = _writeDescriptorCompletions.removeValue(forKey: uuidArgs)
if writeDescriptorCompletions != nil {
let completions = writeDescriptorCompletions!.values
for completion in completions {
completion(.failure(errorNotNil))
}
}
let stateArgs = false
_api.onConnectionStateChanged(uuidArgs: uuidArgs, stateArgs: stateArgs) {_ in }
guard let completion = _disconnectCompletions.removeValue(forKey: uuidArgs) else {
return
}
if error == nil {
completion(.success(()))
} else {
completion(.failure(error!))
}
}
func didReadRSSI(peripheral: CBPeripheral, rssi: NSNumber, error: Error?) {
let uuidArgs = peripheral.identifier.toArgs()
guard let completion = _readRssiCompletions.removeValue(forKey: uuidArgs) else {
return
}
if error == nil {
let rssiArgs = rssi.int64Value
completion(.success((rssiArgs)))
} else {
completion(.failure(error!))
}
}
func didDiscoverServices(peripheral: CBPeripheral, error: Error?) {
let uuidArgs = peripheral.identifier.toArgs()
guard let completion = _discoverServicesCompletions.removeValue(forKey: uuidArgs) else {
return
}
if error == nil {
let services = peripheral.services ?? []
let servicesArgs = services.map { service in service.toArgs() }
let elements = services.flatMap { service in
let hashCodeArgs = service.hash.toInt64()
return [hashCodeArgs: service]
}
var items = _services[uuidArgs]
if items == nil {
_services[uuidArgs] = Dictionary(uniqueKeysWithValues: elements)
} else {
items!.merge(elements) { service1, service2 in service2 }
}
completion(.success(servicesArgs))
} else {
completion(.failure(error!))
}
}
func didDiscoverCharacteristics(peripheral: CBPeripheral, service: CBService, error: Error?) {
let uuidArgs = peripheral.identifier.toArgs()
let hashCodeArgs = service.hash.toInt64()
guard var completions = _discoverCharacteristicsCompletions[uuidArgs] else {
return
}
guard let completion = completions.removeValue(forKey: hashCodeArgs) else {
return
}
if error == nil {
let characteristics = service.characteristics ?? []
let characteristicsArgs = characteristics.map { characteristic in characteristic.toArgs() }
let elements = characteristics.flatMap { characteristic in
let hashCodeArgs = characteristic.hash.toInt64()
return [hashCodeArgs: characteristic]
}
var items = _characteristics[uuidArgs]
if items == nil {
_characteristics[uuidArgs] = Dictionary(uniqueKeysWithValues: elements)
} else {
items!.merge(elements) { characteristic1, characteristic2 in characteristic2 }
}
completion(.success(characteristicsArgs))
} else {
completion(.failure(error!))
}
}
func didDiscoverDescriptors(peripheral: CBPeripheral, characteristic: CBCharacteristic, error: Error?) {
let uuidArgs = peripheral.identifier.toArgs()
let hashCodeArgs = characteristic.hash.toInt64()
guard var completions = _discoverDescriptorsCompletions[uuidArgs] else {
return
}
guard let completion = completions.removeValue(forKey: hashCodeArgs) else {
return
}
if error == nil {
let descriptors = characteristic.descriptors ?? []
let descriptorsArgs = descriptors.map { descriptor in descriptor.toArgs() }
let elements = descriptors.flatMap { descriptor in
let hashCodeArgs = descriptor.hash.toInt64()
return [hashCodeArgs: descriptor]
}
var items = _descriptors[uuidArgs]
if items == nil {
_descriptors[uuidArgs] = Dictionary(uniqueKeysWithValues: elements)
} else {
items!.merge(elements) { descriptor1, descriptor2 in descriptor2 }
}
completion(.success(descriptorsArgs))
} else {
completion(.failure(error!))
}
}
func didUpdateCharacteristicValue(peripheral: CBPeripheral, characteristic: CBCharacteristic, error: Error?) {
let uuidArgs = peripheral.identifier.toArgs()
let hashCodeArgs = characteristic.hash.toInt64()
let value = characteristic.value ?? Data()
let valueArgs = FlutterStandardTypedData(bytes: value)
var completions = _readCharacteristicCompletions[uuidArgs]
guard let completion = completions?.removeValue(forKey: hashCodeArgs) else {
_api.onCharacteristicNotified(uuidArgs: uuidArgs, hashCodeArgs: hashCodeArgs, valueArgs: valueArgs) {_ in }
return
}
if error == nil {
completion(.success(valueArgs))
} else {
completion(.failure(error!))
}
}
func didWriteCharacteristicValue(peripheral: CBPeripheral, characteristic: CBCharacteristic, error: Error?) {
let uuidArgs = peripheral.identifier.toArgs()
let hashCodeArgs = characteristic.hash.toInt64()
guard var completions = _writeCharacteristicCompletions[uuidArgs] else {
return
}
guard let completion = completions.removeValue(forKey: hashCodeArgs) else {
return
}
if error == nil {
completion(.success(()))
} else {
completion(.failure(error!))
}
}
func didUpdateCharacteristicNotificationState(peripheral: CBPeripheral, characteristic: CBCharacteristic, error: Error?) {
let uuidArgs = peripheral.identifier.toArgs()
let hashCodeArgs = characteristic.hash.toInt64()
guard var completions = _setCharacteristicNotifyStateCompletions[uuidArgs] else {
return
}
guard let completion = completions.removeValue(forKey: hashCodeArgs) else {
return
}
if error == nil {
completion(.success(()))
} else {
completion(.failure(error!))
}
}
func didUpdateDescriptorValue(peripheral: CBPeripheral, descriptor: CBDescriptor, error: Error?) {
let uuidArgs = peripheral.identifier.toArgs()
let hashCodeArgs = descriptor.hash.toInt64()
guard var completions = _readDescriptorCompletions[uuidArgs] else {
return
}
guard let completion = completions.removeValue(forKey: hashCodeArgs) else {
return
}
if error == nil {
// TODO: confirm the corresponding descriptor types and values are correct.
let valueArgs: FlutterStandardTypedData
let value = descriptor.value
do {
switch descriptor.uuid.uuidString {
case CBUUIDCharacteristicExtendedPropertiesString:
fallthrough
case CBUUIDClientCharacteristicConfigurationString:
fallthrough
case CBUUIDServerCharacteristicConfigurationString:
guard let numberValue = value as? NSNumber else {
throw MyError.illegalArgument
}
valueArgs = FlutterStandardTypedData(bytes: numberValue.data)
case CBUUIDCharacteristicUserDescriptionString:
fallthrough
case CBUUIDCharacteristicAggregateFormatString:
guard let stringValue = value as? String else {
throw MyError.illegalArgument
}
valueArgs = FlutterStandardTypedData(bytes: stringValue.data)
case CBUUIDCharacteristicFormatString:
guard let bytes = value as? Data else {
throw MyError.illegalArgument
}
valueArgs = FlutterStandardTypedData(bytes: bytes)
case CBUUIDL2CAPPSMCharacteristicString:
guard let uint16Value = value as? UInt16 else {
throw MyError.illegalArgument
}
valueArgs = FlutterStandardTypedData(bytes: uint16Value.data)
default:
throw MyError.illegalArgument
}
} catch {
valueArgs = FlutterStandardTypedData()
}
completion(.success((valueArgs)))
} else {
completion(.failure(error!))
}
}
func didWriteDescriptorValue(peripheral: CBPeripheral, descriptor: CBDescriptor, error: Error?) {
let uuidArgs = peripheral.identifier.toArgs()
let hashCodeArgs = descriptor.hash.toInt64()
guard var completions = _writeDescriptorCompletions[uuidArgs] else {
return
}
guard let completion = completions.removeValue(forKey: hashCodeArgs) else {
return
}
if error == nil {
completion(.success(()))
} else {
completion(.failure(error!))
}
}
private func _clearState() {
if(_centralManager.isScanning) {
_centralManager.stopScan()
}
for peripheral in _peripherals.values {
if peripheral.state != .disconnected {
_centralManager.cancelPeripheralConnection(peripheral)
}
}
_peripherals.removeAll()
_services.removeAll()
_characteristics.removeAll()
_descriptors.removeAll()
_connectCompletions.removeAll()
_disconnectCompletions.removeAll()
_readRssiCompletions.removeAll()
_discoverServicesCompletions.removeAll()
_discoverCharacteristicsCompletions.removeAll()
_discoverDescriptorsCompletions.removeAll()
_readCharacteristicCompletions.removeAll()
_writeCharacteristicCompletions.removeAll()
_setCharacteristicNotifyStateCompletions.removeAll()
_readDescriptorCompletions.removeAll()
_writeDescriptorCompletions.removeAll()
}
private func _retrieveService(uuidArgs: String, hashCodeArgs: Int64) -> CBService? {
guard let services = _services[uuidArgs] else {
return nil
}
return services[hashCodeArgs]
}
private func _retrieveCharacteristic(uuidArgs: String, hashCodeArgs: Int64) -> CBCharacteristic? {
guard let characteristics = _characteristics[uuidArgs] else {
return nil
}
return characteristics[hashCodeArgs]
}
private func _retrieveDescriptor(uuidArgs: String, hashCodeArgs: Int64) -> CBDescriptor? {
guard let descriptors = _descriptors[uuidArgs] else {
return nil
}
return descriptors[hashCodeArgs]
}
private func _onStateChanged() {
let state = _centralManager.state
let stateArgs = state.toArgs()
let stateNumberArgs = stateArgs.rawValue.toInt64()
_api.onStateChanged(stateNumberArgs: stateNumberArgs) {_ in }
}
}