Files
bluetooth_low_energy/ios/Classes/MyPeripheralDelegate.swift

212 lines
9.6 KiB
Swift

//
// MyPeripheralDelegate.swift
// bluetooth_low_energy
//
// Created by on 2022/9/20.
//
import Foundation
import CoreBluetooth
class MyPeripheralDelegate: NSObject, CBPeripheralDelegate {
func peripheral(_ peripheral: CBPeripheral, didDiscoverServices error: Error?) {
let id = String(peripheral.hash)
let completion = instances.removeValue(forKey: "\(id)/\(KEY_DISCOVER_SERVICES_COMPLETION)") as! ([FlutterStandardTypedData]?, FlutterError?) -> Void
if error == nil {
var serviceBuffers = [FlutterStandardTypedData]()
let services = peripheral.services
if services != nil {
for service in services! {
let serviceBuffer = registerService(service)
serviceBuffers.append(serviceBuffer)
}
}
completion(serviceBuffers, nil)
} else {
let errorMessage = error!.localizedDescription
let flutterError = FlutterError(code: BLUETOOTH_LOW_ENERGY_ERROR, message: errorMessage, details: nil)
completion(nil, flutterError)
}
}
func peripheral(_ peripheral: CBPeripheral, didDiscoverCharacteristicsFor service: CBService, error: Error?) {
let id = String(service.hash)
let completion = instances.removeValue(forKey: "\(id)/\(KEY_DISCOVER_CHARACTERISTICS_COMPLETION)") as! ([FlutterStandardTypedData]?, FlutterError?) -> Void
if error == nil {
var characteristicBuffers = [FlutterStandardTypedData]()
let characteristics = service.characteristics
if characteristics != nil {
for characteristic in characteristics! {
let characteristicBuffer = registerCharacteristic(characteristic)
characteristicBuffers.append(characteristicBuffer)
}
}
completion(characteristicBuffers, nil)
} else {
let errorMessage = error!.localizedDescription
let flutterError = FlutterError(code: BLUETOOTH_LOW_ENERGY_ERROR, message: errorMessage, details: nil)
completion(nil, flutterError)
}
}
func peripheral(_ peripheral: CBPeripheral, didDiscoverDescriptorsFor characteristic: CBCharacteristic, error: Error?) {
let id = String(characteristic.hash)
let completion = instances.removeValue(forKey: "\(id)/\(KEY_DISCOVER_DESCRIPTORS_COMPLETION)") as! ([FlutterStandardTypedData]?, FlutterError?) -> Void
if error == nil {
var descriptorBuffers = [FlutterStandardTypedData]()
let descriptors = characteristic.descriptors
if descriptors != nil {
for descriptor in descriptors! {
let descriptorBuffer = registerDescriptor(descriptor)
descriptorBuffers.append(descriptorBuffer)
}
}
completion(descriptorBuffers, nil)
} else {
let errorMessage = error!.localizedDescription
let flutterError = FlutterError(code: BLUETOOTH_LOW_ENERGY_ERROR, message: errorMessage, details: nil)
completion(nil, flutterError)
}
}
func peripheral(_ peripheral: CBPeripheral, didUpdateValueFor characteristic: CBCharacteristic, error: Error?) {
let id = String(characteristic.hash)
let completion = instances.removeValue(forKey: "\(id)/\(KEY_READ_COMPLETION)") as? (FlutterStandardTypedData?, FlutterError?) -> Void
let characteristicValue = characteristic.value
let value = characteristicValue == nil ? FlutterStandardTypedData() : FlutterStandardTypedData(bytes: characteristicValue!)
if completion == nil {
characteristicFlutterApi.onValueChanged(id, value: value) {_ in }
} else if error == nil {
completion!(value, nil)
} else {
let errorMessage = error!.localizedDescription
let flutterError = FlutterError(code: BLUETOOTH_LOW_ENERGY_ERROR, message: errorMessage, details: nil)
completion!(nil, flutterError)
}
}
func peripheral(_ peripheral: CBPeripheral, didWriteValueFor characteristic: CBCharacteristic, error: Error?) {
let id = String(characteristic.hash)
let completion = instances.removeValue(forKey: "\(id)/\(KEY_WRITE_COMPLETION)") as! (FlutterError?) -> Void
if error == nil {
completion(nil)
} else {
let errorMessage = error!.localizedDescription
let flutterError = FlutterError(code: BLUETOOTH_LOW_ENERGY_ERROR, message: errorMessage, details: nil)
completion(flutterError)
}
}
func peripheral(_ peripheral: CBPeripheral, didUpdateNotificationStateFor characteristic: CBCharacteristic, error: Error?) {
let id = String(characteristic.hash)
let completion = instances.removeValue(forKey: "\(id)/\(KEY_SET_NOTIFY_COMPLETION)") as! (FlutterError?) -> Void
if error == nil {
completion(nil)
} else {
let errorMessage = error!.localizedDescription
let flutterError = FlutterError(code: BLUETOOTH_LOW_ENERGY_ERROR, message: errorMessage, details: nil)
completion(flutterError)
}
}
func peripheral(_ peripheral: CBPeripheral, didUpdateValueFor descriptor: CBDescriptor, error: Error?) {
let id = String(descriptor.hash)
let completion = instances.removeValue(forKey: "\(id)/\(KEY_READ_COMPLETION)") as! (FlutterStandardTypedData?, FlutterError?) -> Void
if error == nil {
let value: FlutterStandardTypedData
if descriptor.value == nil {
value = FlutterStandardTypedData()
} else {
switch descriptor.uuid.uuidString {
case CBUUIDCharacteristicExtendedPropertiesString:
fallthrough
case CBUUIDClientCharacteristicConfigurationString:
fallthrough
case CBUUIDServerCharacteristicConfigurationString:
let item = descriptor.value as! NSNumber
value = FlutterStandardTypedData(bytes: item.data)
case CBUUIDCharacteristicUserDescriptionString:
fallthrough
case CBUUIDCharacteristicAggregateFormatString:
let item = descriptor.value as! String
value = FlutterStandardTypedData(bytes: item.data)
case CBUUIDCharacteristicFormatString:
let data = descriptor.value as! Data
value = FlutterStandardTypedData(bytes: data)
case CBUUIDL2CAPPSMCharacteristicString:
let item = descriptor.value as! UInt16
value = FlutterStandardTypedData(bytes: item.data)
default:
value = FlutterStandardTypedData()
}
}
completion(value, nil)
} else {
let errorMessage = error!.localizedDescription
let flutterError = FlutterError(code: BLUETOOTH_LOW_ENERGY_ERROR, message: errorMessage, details: nil)
completion(nil, flutterError)
}
}
func peripheral(_ peripheral: CBPeripheral, didWriteValueFor descriptor: CBDescriptor, error: Error?) {
let id = String(descriptor.hash)
let completion = instances.removeValue(forKey: "\(id)/\(KEY_WRITE_COMPLETION)") as! (FlutterError?) -> Void
if error == nil {
completion(nil)
} else {
let errorMessage = error!.localizedDescription
let flutterError = FlutterError(code: BLUETOOTH_LOW_ENERGY_ERROR, message: errorMessage, details: nil)
completion(flutterError)
}
}
private func registerService(_ service: CBService) -> FlutterStandardTypedData {
let id = String(service.hash)
var items = register(id)
items[KEY_SERVICE] = service
// This is a copy on write.
instances[id] = items
let data = try! Proto_GattService.with {
$0.id = id
$0.uuid = Proto_UUID.with {
$0.value = service.uuid.uuidString
}
}.serializedData()
return FlutterStandardTypedData(bytes: data)
}
private func registerCharacteristic(_ characteristic: CBCharacteristic) -> FlutterStandardTypedData {
let id = String(characteristic.hash)
var items = register(id)
items[KEY_CHARACTERISTIC] = characteristic
// This is a copy on write.
instances[id] = items
let data = try! Proto_GattCharacteristic.with {
$0.id = id
$0.uuid = Proto_UUID.with {
$0.value = characteristic.uuid.uuidString
}
$0.canRead = characteristic.properties.contains(.read)
$0.canWrite = characteristic.properties.contains(.write)
$0.canWriteWithoutResponse = characteristic.properties.contains(.writeWithoutResponse)
$0.canNotify = characteristic.properties.contains(.notify)
}.serializedData()
return FlutterStandardTypedData(bytes: data)
}
private func registerDescriptor(_ descriptor: CBDescriptor) -> FlutterStandardTypedData {
let id = String(descriptor.hash)
var items = register(id)
items[KEY_DESCRIPTOR] = descriptor
// This is a copy on write.
instances[id] = items
let data = try! Proto_GattDescriptor.with {
$0.id = id
$0.uuid = Proto_UUID.with {
$0.value = descriptor.uuid.uuidString
}
}.serializedData()
return FlutterStandardTypedData(bytes: data)
}
}