2.0.1 (#10)
* fix: 修复 iOS 和 macOS 断开后 GATT 被清理导致操作无法完成的问题 * fix: 调整 GATT 缓存 * fix: 修改 iOS 蓝牙使用描述 * fix: 修复无法通过设备地址生成 UUID 的问题,修复由于 bluez 未重写 hashCode 和 equals 导致无法比较缓存实例的问题 * fix: 修改版本信息 * fix: 修复BUG * fix: 调整示例程序 * fix: 优化代码 * fix: 修改版本号 * fix: 更新 REDEME.md * fix: 更新依赖项 * fix: 项目调整 --------- Co-authored-by: jetson2 <jetson2@const.cc>
This commit is contained in:
@ -1,3 +1,9 @@
|
||||
## 2.0.1
|
||||
|
||||
- Fix the issue that GATTs is cleared after peripheral disconnected on iOS and macOS.
|
||||
- Fix the issue that create UUID form peripheral's address failed on Linux.
|
||||
- Fix the issue that instance match failed on Linux.
|
||||
|
||||
## 2.0.0
|
||||
|
||||
- Rewrite the whole project with federated plugins.
|
||||
|
@ -258,11 +258,11 @@ protocol MyCentralControllerHostApi {
|
||||
func getServices(myPeripheralKey: Int64) throws -> [MyGattServiceArgs]
|
||||
func getCharacteristics(myServiceKey: Int64) throws -> [MyGattCharacteristicArgs]
|
||||
func getDescriptors(myCharacteristicKey: Int64) throws -> [MyGattDescriptorArgs]
|
||||
func readCharacteristic(myPeripheralKey: Int64, myCharacteristicKey: Int64, completion: @escaping (Result<FlutterStandardTypedData, Error>) -> Void)
|
||||
func writeCharacteristic(myPeripheralKey: Int64, myCharacteristicKey: Int64, value: FlutterStandardTypedData, myTypeNumber: Int64, completion: @escaping (Result<Void, Error>) -> Void)
|
||||
func notifyCharacteristic(myPeripheralKey: Int64, myCharacteristicKey: Int64, state: Bool, completion: @escaping (Result<Void, Error>) -> Void)
|
||||
func readDescriptor(myPeripheralKey: Int64, myDescriptorKey: Int64, completion: @escaping (Result<FlutterStandardTypedData, Error>) -> Void)
|
||||
func writeDescriptor(myPeripheralKey: Int64, myDescriptorKey: Int64, value: FlutterStandardTypedData, completion: @escaping (Result<Void, Error>) -> Void)
|
||||
func readCharacteristic(myPeripheralKey: Int64, myServiceKey: Int64, myCharacteristicKey: Int64, completion: @escaping (Result<FlutterStandardTypedData, Error>) -> Void)
|
||||
func writeCharacteristic(myPeripheralKey: Int64, myServiceKey: Int64, myCharacteristicKey: Int64, value: FlutterStandardTypedData, myTypeNumber: Int64, completion: @escaping (Result<Void, Error>) -> Void)
|
||||
func notifyCharacteristic(myPeripheralKey: Int64, myServiceKey: Int64, myCharacteristicKey: Int64, state: Bool, completion: @escaping (Result<Void, Error>) -> Void)
|
||||
func readDescriptor(myPeripheralKey: Int64, myCharacteristicKey: Int64, myDescriptorKey: Int64, completion: @escaping (Result<FlutterStandardTypedData, Error>) -> Void)
|
||||
func writeDescriptor(myPeripheralKey: Int64, myCharacteristicKey: Int64, myDescriptorKey: Int64, value: FlutterStandardTypedData, completion: @escaping (Result<Void, Error>) -> Void)
|
||||
}
|
||||
|
||||
/// Generated setup class from Pigeon to handle messages through the `binaryMessenger`.
|
||||
@ -426,8 +426,9 @@ class MyCentralControllerHostApiSetup {
|
||||
readCharacteristicChannel.setMessageHandler { message, reply in
|
||||
let args = message as! [Any?]
|
||||
let myPeripheralKeyArg = args[0] is Int64 ? args[0] as! Int64 : Int64(args[0] as! Int32)
|
||||
let myCharacteristicKeyArg = args[1] is Int64 ? args[1] as! Int64 : Int64(args[1] as! Int32)
|
||||
api.readCharacteristic(myPeripheralKey: myPeripheralKeyArg, myCharacteristicKey: myCharacteristicKeyArg) { result in
|
||||
let myServiceKeyArg = args[1] is Int64 ? args[1] as! Int64 : Int64(args[1] as! Int32)
|
||||
let myCharacteristicKeyArg = args[2] is Int64 ? args[2] as! Int64 : Int64(args[2] as! Int32)
|
||||
api.readCharacteristic(myPeripheralKey: myPeripheralKeyArg, myServiceKey: myServiceKeyArg, myCharacteristicKey: myCharacteristicKeyArg) { result in
|
||||
switch result {
|
||||
case .success(let res):
|
||||
reply(wrapResult(res))
|
||||
@ -444,10 +445,11 @@ class MyCentralControllerHostApiSetup {
|
||||
writeCharacteristicChannel.setMessageHandler { message, reply in
|
||||
let args = message as! [Any?]
|
||||
let myPeripheralKeyArg = args[0] is Int64 ? args[0] as! Int64 : Int64(args[0] as! Int32)
|
||||
let myCharacteristicKeyArg = args[1] is Int64 ? args[1] as! Int64 : Int64(args[1] as! Int32)
|
||||
let valueArg = args[2] as! FlutterStandardTypedData
|
||||
let myTypeNumberArg = args[3] is Int64 ? args[3] as! Int64 : Int64(args[3] as! Int32)
|
||||
api.writeCharacteristic(myPeripheralKey: myPeripheralKeyArg, myCharacteristicKey: myCharacteristicKeyArg, value: valueArg, myTypeNumber: myTypeNumberArg) { result in
|
||||
let myServiceKeyArg = args[1] is Int64 ? args[1] as! Int64 : Int64(args[1] as! Int32)
|
||||
let myCharacteristicKeyArg = args[2] is Int64 ? args[2] as! Int64 : Int64(args[2] as! Int32)
|
||||
let valueArg = args[3] as! FlutterStandardTypedData
|
||||
let myTypeNumberArg = args[4] is Int64 ? args[4] as! Int64 : Int64(args[4] as! Int32)
|
||||
api.writeCharacteristic(myPeripheralKey: myPeripheralKeyArg, myServiceKey: myServiceKeyArg, myCharacteristicKey: myCharacteristicKeyArg, value: valueArg, myTypeNumber: myTypeNumberArg) { result in
|
||||
switch result {
|
||||
case .success:
|
||||
reply(wrapResult(nil))
|
||||
@ -464,9 +466,10 @@ class MyCentralControllerHostApiSetup {
|
||||
notifyCharacteristicChannel.setMessageHandler { message, reply in
|
||||
let args = message as! [Any?]
|
||||
let myPeripheralKeyArg = args[0] is Int64 ? args[0] as! Int64 : Int64(args[0] as! Int32)
|
||||
let myCharacteristicKeyArg = args[1] is Int64 ? args[1] as! Int64 : Int64(args[1] as! Int32)
|
||||
let stateArg = args[2] as! Bool
|
||||
api.notifyCharacteristic(myPeripheralKey: myPeripheralKeyArg, myCharacteristicKey: myCharacteristicKeyArg, state: stateArg) { result in
|
||||
let myServiceKeyArg = args[1] is Int64 ? args[1] as! Int64 : Int64(args[1] as! Int32)
|
||||
let myCharacteristicKeyArg = args[2] is Int64 ? args[2] as! Int64 : Int64(args[2] as! Int32)
|
||||
let stateArg = args[3] as! Bool
|
||||
api.notifyCharacteristic(myPeripheralKey: myPeripheralKeyArg, myServiceKey: myServiceKeyArg, myCharacteristicKey: myCharacteristicKeyArg, state: stateArg) { result in
|
||||
switch result {
|
||||
case .success:
|
||||
reply(wrapResult(nil))
|
||||
@ -483,8 +486,9 @@ class MyCentralControllerHostApiSetup {
|
||||
readDescriptorChannel.setMessageHandler { message, reply in
|
||||
let args = message as! [Any?]
|
||||
let myPeripheralKeyArg = args[0] is Int64 ? args[0] as! Int64 : Int64(args[0] as! Int32)
|
||||
let myDescriptorKeyArg = args[1] is Int64 ? args[1] as! Int64 : Int64(args[1] as! Int32)
|
||||
api.readDescriptor(myPeripheralKey: myPeripheralKeyArg, myDescriptorKey: myDescriptorKeyArg) { result in
|
||||
let myCharacteristicKeyArg = args[1] is Int64 ? args[1] as! Int64 : Int64(args[1] as! Int32)
|
||||
let myDescriptorKeyArg = args[2] is Int64 ? args[2] as! Int64 : Int64(args[2] as! Int32)
|
||||
api.readDescriptor(myPeripheralKey: myPeripheralKeyArg, myCharacteristicKey: myCharacteristicKeyArg, myDescriptorKey: myDescriptorKeyArg) { result in
|
||||
switch result {
|
||||
case .success(let res):
|
||||
reply(wrapResult(res))
|
||||
@ -501,9 +505,10 @@ class MyCentralControllerHostApiSetup {
|
||||
writeDescriptorChannel.setMessageHandler { message, reply in
|
||||
let args = message as! [Any?]
|
||||
let myPeripheralKeyArg = args[0] is Int64 ? args[0] as! Int64 : Int64(args[0] as! Int32)
|
||||
let myDescriptorKeyArg = args[1] is Int64 ? args[1] as! Int64 : Int64(args[1] as! Int32)
|
||||
let valueArg = args[2] as! FlutterStandardTypedData
|
||||
api.writeDescriptor(myPeripheralKey: myPeripheralKeyArg, myDescriptorKey: myDescriptorKeyArg, value: valueArg) { result in
|
||||
let myCharacteristicKeyArg = args[1] is Int64 ? args[1] as! Int64 : Int64(args[1] as! Int32)
|
||||
let myDescriptorKeyArg = args[2] is Int64 ? args[2] as! Int64 : Int64(args[2] as! Int32)
|
||||
let valueArg = args[3] as! FlutterStandardTypedData
|
||||
api.writeDescriptor(myPeripheralKey: myPeripheralKeyArg, myCharacteristicKey: myCharacteristicKeyArg, myDescriptorKey: myDescriptorKeyArg, value: valueArg) { result in
|
||||
switch result {
|
||||
case .success:
|
||||
reply(wrapResult(nil))
|
||||
|
@ -19,10 +19,10 @@ class MyCentralController: MyCentralControllerHostApi {
|
||||
private lazy var myPeripheralDelegate = MyPeripheralDelegate(self)
|
||||
private let centralManager = CBCentralManager()
|
||||
|
||||
private var peripherals = [Int: CBPeripheral]()
|
||||
private var services = [Int: CBService]()
|
||||
private var characteristics = [Int: CBCharacteristic]()
|
||||
private var descriptors = [Int: CBDescriptor]()
|
||||
private var cachedPeripherals = [Int: CBPeripheral]()
|
||||
private var cachedServices = [Int: [Int: CBService]]()
|
||||
private var cachedCharacteristics = [Int: [Int: CBCharacteristic]]()
|
||||
private var cachedDescriptors = [Int: [Int: CBDescriptor]]()
|
||||
|
||||
var setUpCompletion: ((Result<MyCentralControllerArgs, Error>) -> Void)?
|
||||
var connectCompletions = [Int: (Result<Void, Error>) -> Void]()
|
||||
@ -61,16 +61,16 @@ class MyCentralController: MyCentralControllerHostApi {
|
||||
if(centralManager.isScanning) {
|
||||
centralManager.stopScan()
|
||||
}
|
||||
for peripheral in peripherals.values {
|
||||
for peripheral in cachedPeripherals.values {
|
||||
peripheral.delegate = nil
|
||||
if peripheral.state != .disconnected {
|
||||
centralManager.cancelPeripheralConnection(peripheral)
|
||||
}
|
||||
}
|
||||
peripherals.removeAll()
|
||||
services.removeAll()
|
||||
characteristics.removeAll()
|
||||
descriptors.removeAll()
|
||||
cachedPeripherals.removeAll()
|
||||
cachedServices.removeAll()
|
||||
cachedCharacteristics.removeAll()
|
||||
cachedDescriptors.removeAll()
|
||||
}
|
||||
|
||||
func startDiscovery() throws {
|
||||
@ -89,7 +89,7 @@ class MyCentralController: MyCentralControllerHostApi {
|
||||
if unfinishedCompletion != nil {
|
||||
throw MyError.illegalState
|
||||
}
|
||||
guard let peripheral = peripherals[peripheralKey] else {
|
||||
guard let peripheral = cachedPeripherals[peripheralKey] else {
|
||||
throw MyError.illegalArgument
|
||||
}
|
||||
centralManager.connect(peripheral)
|
||||
@ -106,7 +106,7 @@ class MyCentralController: MyCentralControllerHostApi {
|
||||
if unfinishedCompletion != nil {
|
||||
throw MyError.illegalState
|
||||
}
|
||||
guard let peripheral = peripherals[peripheralKey] else {
|
||||
guard let peripheral = cachedPeripherals[peripheralKey] else {
|
||||
throw MyError.illegalArgument
|
||||
}
|
||||
centralManager.cancelPeripheralConnection(peripheral)
|
||||
@ -123,7 +123,7 @@ class MyCentralController: MyCentralControllerHostApi {
|
||||
if unfinishedCompletion != nil {
|
||||
throw MyError.illegalState
|
||||
}
|
||||
guard let peripheral = peripherals[peripheralKey] else {
|
||||
guard let peripheral = cachedPeripherals[peripheralKey] else {
|
||||
throw MyError.illegalArgument
|
||||
}
|
||||
peripheral.discoverServices(nil)
|
||||
@ -135,53 +135,42 @@ class MyCentralController: MyCentralControllerHostApi {
|
||||
|
||||
func getServices(myPeripheralKey: Int64) throws -> [MyGattServiceArgs] {
|
||||
let peripheralKey = Int(myPeripheralKey)
|
||||
guard let peripheral = peripherals[peripheralKey] else {
|
||||
guard let services = cachedServices[peripheralKey] else {
|
||||
throw MyError.illegalArgument
|
||||
}
|
||||
let services = peripheral.services ?? []
|
||||
return services.map { service in
|
||||
let serviceKey = service.hash
|
||||
if self.services[serviceKey] == nil {
|
||||
self.services[serviceKey] = service
|
||||
}
|
||||
return services.map { (key, service) in
|
||||
return service.toMyArgs()
|
||||
}
|
||||
}
|
||||
|
||||
func getCharacteristics(myServiceKey: Int64) throws -> [MyGattCharacteristicArgs] {
|
||||
let serviceKey = Int(myServiceKey)
|
||||
guard let service = services[serviceKey] else {
|
||||
guard let characteristics = cachedCharacteristics[serviceKey] else {
|
||||
throw MyError.illegalArgument
|
||||
}
|
||||
let characteristics = service.characteristics ?? []
|
||||
return characteristics.map { characteristic in
|
||||
let characteristicKey = characteristic.hash
|
||||
if self.characteristics[characteristicKey] == nil {
|
||||
self.characteristics[characteristicKey] = characteristic
|
||||
}
|
||||
return characteristics.map { (key, characteristic) in
|
||||
return characteristic.toMyArgs()
|
||||
}
|
||||
}
|
||||
|
||||
func getDescriptors(myCharacteristicKey: Int64) throws -> [MyGattDescriptorArgs] {
|
||||
let characteristicKey = Int(myCharacteristicKey)
|
||||
guard let characteristic = characteristics[characteristicKey] else {
|
||||
guard let descriptors = cachedDescriptors[characteristicKey] else {
|
||||
throw MyError.illegalArgument
|
||||
}
|
||||
let descritors = characteristic.descriptors ?? []
|
||||
return descritors.map { descriptor in
|
||||
let descriptorKey = descriptor.hash
|
||||
if self.descriptors[descriptorKey] == nil {
|
||||
self.descriptors[descriptorKey] = descriptor
|
||||
}
|
||||
return descriptors.map { (key, descriptor) in
|
||||
return descriptor.toMyArgs()
|
||||
}
|
||||
}
|
||||
|
||||
func readCharacteristic(myPeripheralKey: Int64, myCharacteristicKey: Int64, completion: @escaping (Result<FlutterStandardTypedData, Error>) -> Void) {
|
||||
func readCharacteristic(myPeripheralKey: Int64, myServiceKey: Int64, myCharacteristicKey: Int64, completion: @escaping (Result<FlutterStandardTypedData, Error>) -> Void) {
|
||||
do {
|
||||
let peripheralKey = Int(myPeripheralKey)
|
||||
guard let peripheral = peripherals[peripheralKey] else {
|
||||
guard let peripheral = cachedPeripherals[peripheralKey] else {
|
||||
throw MyError.illegalArgument
|
||||
}
|
||||
let serviceKey = Int(myServiceKey)
|
||||
guard let characteristics = cachedCharacteristics[serviceKey] else {
|
||||
throw MyError.illegalArgument
|
||||
}
|
||||
let characteristicKey = Int(myCharacteristicKey)
|
||||
@ -199,10 +188,14 @@ class MyCentralController: MyCentralControllerHostApi {
|
||||
}
|
||||
}
|
||||
|
||||
func writeCharacteristic(myPeripheralKey: Int64, myCharacteristicKey: Int64, value: FlutterStandardTypedData, myTypeNumber: Int64, completion: @escaping (Result<Void, Error>) -> Void) {
|
||||
func writeCharacteristic(myPeripheralKey: Int64, myServiceKey: Int64, myCharacteristicKey: Int64, value: FlutterStandardTypedData, myTypeNumber: Int64, completion: @escaping (Result<Void, Error>) -> Void) {
|
||||
do {
|
||||
let peripheralKey = Int(myPeripheralKey)
|
||||
guard let peripheral = peripherals[peripheralKey] else {
|
||||
guard let peripheral = cachedPeripherals[peripheralKey] else {
|
||||
throw MyError.illegalArgument
|
||||
}
|
||||
let serviceKey = Int(myServiceKey)
|
||||
guard let characteristics = cachedCharacteristics[serviceKey] else {
|
||||
throw MyError.illegalArgument
|
||||
}
|
||||
let characteristicKey = Int(myCharacteristicKey)
|
||||
@ -226,10 +219,14 @@ class MyCentralController: MyCentralControllerHostApi {
|
||||
}
|
||||
}
|
||||
|
||||
func notifyCharacteristic(myPeripheralKey: Int64, myCharacteristicKey: Int64, state: Bool, completion: @escaping (Result<Void, Error>) -> Void) {
|
||||
func notifyCharacteristic(myPeripheralKey: Int64, myServiceKey: Int64, myCharacteristicKey: Int64, state: Bool, completion: @escaping (Result<Void, Error>) -> Void) {
|
||||
do {
|
||||
let peripheralKey = Int(myPeripheralKey)
|
||||
guard let peripheral = peripherals[peripheralKey] else {
|
||||
guard let peripheral = cachedPeripherals[peripheralKey] else {
|
||||
throw MyError.illegalArgument
|
||||
}
|
||||
let serviceKey = Int(myServiceKey)
|
||||
guard let characteristics = cachedCharacteristics[serviceKey] else {
|
||||
throw MyError.illegalArgument
|
||||
}
|
||||
let characteristicKey = Int(myCharacteristicKey)
|
||||
@ -247,10 +244,14 @@ class MyCentralController: MyCentralControllerHostApi {
|
||||
}
|
||||
}
|
||||
|
||||
func readDescriptor(myPeripheralKey: Int64, myDescriptorKey: Int64, completion: @escaping (Result<FlutterStandardTypedData, Error>) -> Void) {
|
||||
func readDescriptor(myPeripheralKey: Int64, myCharacteristicKey: Int64, myDescriptorKey: Int64, completion: @escaping (Result<FlutterStandardTypedData, Error>) -> Void) {
|
||||
do {
|
||||
let peripheralKey = Int(myPeripheralKey)
|
||||
guard let peripheral = peripherals[peripheralKey] else {
|
||||
guard let peripheral = cachedPeripherals[peripheralKey] else {
|
||||
throw MyError.illegalArgument
|
||||
}
|
||||
let characteristicKey = Int(myCharacteristicKey)
|
||||
guard let descriptors = cachedDescriptors[characteristicKey] else {
|
||||
throw MyError.illegalArgument
|
||||
}
|
||||
let descriptorKey = Int(myDescriptorKey)
|
||||
@ -268,10 +269,14 @@ class MyCentralController: MyCentralControllerHostApi {
|
||||
}
|
||||
}
|
||||
|
||||
func writeDescriptor(myPeripheralKey: Int64, myDescriptorKey: Int64, value: FlutterStandardTypedData, completion: @escaping (Result<Void, Error>) -> Void) {
|
||||
func writeDescriptor(myPeripheralKey: Int64, myCharacteristicKey: Int64, myDescriptorKey: Int64, value: FlutterStandardTypedData, completion: @escaping (Result<Void, Error>) -> Void) {
|
||||
do {
|
||||
let peripheralKey = Int(myPeripheralKey)
|
||||
guard let peripheral = peripherals[peripheralKey] else {
|
||||
guard let peripheral = cachedPeripherals[peripheralKey] else {
|
||||
throw MyError.illegalArgument
|
||||
}
|
||||
let characteristicKey = Int(myCharacteristicKey)
|
||||
guard let descriptors = cachedDescriptors[characteristicKey] else {
|
||||
throw MyError.illegalArgument
|
||||
}
|
||||
let descriptorKey = Int(myDescriptorKey)
|
||||
@ -307,9 +312,9 @@ class MyCentralController: MyCentralControllerHostApi {
|
||||
|
||||
func didDiscover(_ peripheral: CBPeripheral, _ advertisementData: [String : Any], _ rssiNumber: NSNumber) {
|
||||
let peripheralKey = peripheral.hash
|
||||
if peripherals[peripheralKey] == nil {
|
||||
if cachedPeripherals[peripheralKey] == nil {
|
||||
peripheral.delegate = myPeripheralDelegate
|
||||
peripherals[peripheralKey] = peripheral
|
||||
cachedPeripherals[peripheralKey] = peripheral
|
||||
}
|
||||
let myPeripheralArgs = peripheral.toMyArgs()
|
||||
let rssi = rssiNumber.int64Value
|
||||
@ -368,26 +373,24 @@ class MyCentralController: MyCentralControllerHostApi {
|
||||
let myPeripheralKey = Int64(peripheralKey)
|
||||
let discoverGattCompletion = discoverGattCompletions.removeValue(forKey: peripheralKey)
|
||||
if discoverGattCompletion != nil {
|
||||
discoverGattCompletion!(.failure(error ?? MyError.illegalState))
|
||||
didDiscoverGATT(peripheral, error ?? MyError.unknown)
|
||||
}
|
||||
let services = peripheral.services ?? []
|
||||
let services = cachedServices[peripheralKey] ?? [:]
|
||||
for service in services {
|
||||
let characteristics = service.characteristics ?? []
|
||||
let characteristics = cachedCharacteristics[service.key] ?? [:]
|
||||
for characteristic in characteristics {
|
||||
let characteristicKey = characteristic.hash
|
||||
let readCharacteristicCompletion = readCharacteristicCompletions.removeValue(forKey: characteristicKey)
|
||||
let writeCharacteristicCompletion = writeCharacteristicCompletions.removeValue(forKey: characteristicKey)
|
||||
let readCharacteristicCompletion = readCharacteristicCompletions.removeValue(forKey: characteristic.key)
|
||||
let writeCharacteristicCompletion = writeCharacteristicCompletions.removeValue(forKey: characteristic.key)
|
||||
if readCharacteristicCompletion != nil {
|
||||
readCharacteristicCompletion!(.failure(MyError.illegalState))
|
||||
}
|
||||
if writeCharacteristicCompletion != nil {
|
||||
writeCharacteristicCompletion!(.failure(MyError.illegalState))
|
||||
}
|
||||
let descriptors = characteristic.descriptors ?? []
|
||||
let descriptors = cachedDescriptors[characteristic.key] ?? [:]
|
||||
for descriptor in descriptors {
|
||||
let descriptorKey = descriptor.hash
|
||||
let readDescriptorCompletion = readDescriptorCompletions.removeValue(forKey: descriptorKey)
|
||||
let writeDescriptorCompletion = writeDescriptorCompletions.removeValue(forKey: descriptorKey)
|
||||
let readDescriptorCompletion = readDescriptorCompletions.removeValue(forKey: descriptor.key)
|
||||
let writeDescriptorCompletion = writeDescriptorCompletions.removeValue(forKey: descriptor.key)
|
||||
if readDescriptorCompletion != nil {
|
||||
readDescriptorCompletion!(.failure(MyError.illegalState))
|
||||
}
|
||||
@ -411,37 +414,28 @@ class MyCentralController: MyCentralControllerHostApi {
|
||||
|
||||
func didDiscoverServices(_ peripheral: CBPeripheral, _ error: Error?) {
|
||||
let peripheralKey = peripheral.hash
|
||||
guard let completion = discoverGattCompletions[peripheralKey] else {
|
||||
return
|
||||
}
|
||||
if error == nil {
|
||||
var services = peripheral.services ?? []
|
||||
if services.isEmpty {
|
||||
discoverGattCompletions.removeValue(forKey: peripheralKey)
|
||||
completion(.success(()))
|
||||
didDiscoverGATT(peripheral, error)
|
||||
} else {
|
||||
let service = services.removeFirst()
|
||||
unfinishedServices[peripheralKey] = services
|
||||
peripheral.discoverCharacteristics(nil, for: service)
|
||||
}
|
||||
} else {
|
||||
discoverGattCompletions.removeValue(forKey: peripheralKey)
|
||||
completion(.failure(error!))
|
||||
didDiscoverGATT(peripheral, error)
|
||||
}
|
||||
}
|
||||
|
||||
func didDiscoverCharacteristics(_ peripheral: CBPeripheral, _ service: CBService, _ error: Error?) {
|
||||
let peripheralKey = peripheral.hash
|
||||
guard let completion = discoverGattCompletions[peripheralKey] else {
|
||||
return
|
||||
}
|
||||
if error == nil {
|
||||
var characteristics = service.characteristics ?? []
|
||||
if characteristics.isEmpty {
|
||||
var services = unfinishedServices.removeValue(forKey: peripheralKey) ?? []
|
||||
if services.isEmpty {
|
||||
discoverGattCompletions.removeValue(forKey: peripheralKey)
|
||||
completion(.success(()))
|
||||
didDiscoverGATT(peripheral, error)
|
||||
} else {
|
||||
let service = services.removeFirst()
|
||||
unfinishedServices[peripheralKey] = services
|
||||
@ -453,24 +447,18 @@ class MyCentralController: MyCentralControllerHostApi {
|
||||
peripheral.discoverDescriptors(for: characteristic)
|
||||
}
|
||||
} else {
|
||||
discoverGattCompletions.removeValue(forKey: peripheralKey)
|
||||
unfinishedServices.removeValue(forKey: peripheralKey)
|
||||
completion(.failure(error!))
|
||||
didDiscoverGATT(peripheral, error)
|
||||
}
|
||||
}
|
||||
|
||||
func didDiscoverDescriptors(_ peripheral: CBPeripheral, _ characteristic: CBCharacteristic, _ error: Error?) {
|
||||
let peripheralKey = peripheral.hash
|
||||
guard let completion = discoverGattCompletions[peripheralKey] else {
|
||||
return
|
||||
}
|
||||
if error == nil {
|
||||
var characteristics = unfinishedCharacteristics.removeValue(forKey: peripheralKey) ?? []
|
||||
if (characteristics.isEmpty) {
|
||||
var services = unfinishedServices.removeValue(forKey: peripheralKey) ?? []
|
||||
if services.isEmpty {
|
||||
discoverGattCompletions.removeValue(forKey: peripheralKey)
|
||||
completion(.success(()))
|
||||
didDiscoverGATT(peripheral, error)
|
||||
} else {
|
||||
let service = services.removeFirst()
|
||||
unfinishedServices[peripheralKey] = services
|
||||
@ -482,9 +470,41 @@ class MyCentralController: MyCentralControllerHostApi {
|
||||
peripheral.discoverDescriptors(for: characteristic)
|
||||
}
|
||||
} else {
|
||||
discoverGattCompletions.removeValue(forKey: peripheralKey)
|
||||
unfinishedServices.removeValue(forKey: peripheralKey)
|
||||
unfinishedCharacteristics.removeValue(forKey: peripheralKey)
|
||||
didDiscoverGATT(peripheral, error)
|
||||
}
|
||||
}
|
||||
|
||||
private func didDiscoverGATT(_ peripheral: CBPeripheral, _ error: Error?) {
|
||||
let peripheralKey = peripheral.hash
|
||||
unfinishedServices.removeValue(forKey: peripheralKey)
|
||||
unfinishedCharacteristics.removeValue(forKey: peripheralKey)
|
||||
guard let completion = discoverGattCompletions.removeValue(forKey: peripheralKey) else {
|
||||
return
|
||||
}
|
||||
if error == nil {
|
||||
let services = peripheral.services ?? []
|
||||
var cachedServices = [Int: CBService]()
|
||||
for service in services {
|
||||
let serviceKey = service.hash
|
||||
cachedServices[serviceKey] = service
|
||||
let characteristics = service.characteristics ?? []
|
||||
var cachedCharacteristics = [Int: CBCharacteristic]()
|
||||
for characteristic in characteristics {
|
||||
let characteristicKey = characteristic.hash
|
||||
cachedCharacteristics[characteristicKey] = characteristic
|
||||
let descriptors = characteristic.descriptors ?? []
|
||||
var cachedDescriptors = [Int: CBDescriptor]()
|
||||
for descriptor in descriptors {
|
||||
let descriptorKey = descriptor.hash
|
||||
cachedDescriptors[descriptorKey] = descriptor
|
||||
}
|
||||
self.cachedDescriptors[characteristicKey] = cachedDescriptors
|
||||
}
|
||||
self.cachedCharacteristics[serviceKey] = cachedCharacteristics
|
||||
}
|
||||
self.cachedServices[peripheralKey] = cachedServices
|
||||
completion(.success(()))
|
||||
} else {
|
||||
completion(.failure(error!))
|
||||
}
|
||||
}
|
||||
|
@ -1,9 +1,9 @@
|
||||
#
|
||||
# To learn more about a Podspec see http://guides.cocoapods.org/syntax/podspec.html.
|
||||
# Run `pod lib lint bluetooth_low_energy_ios.podspec` to validate before publishing.
|
||||
# Run `pod lib lint bluetooth_low_energy.podspec` to validate before publishing.
|
||||
#
|
||||
Pod::Spec.new do |s|
|
||||
s.name = 'bluetooth_low_energy_ios'
|
||||
s.name = 'bluetooth_low_energy'
|
||||
s.version = '0.0.1'
|
||||
s.summary = 'A new Flutter plugin project.'
|
||||
s.description = <<-DESC
|
||||
@ -15,7 +15,7 @@ A new Flutter plugin project.
|
||||
s.source = { :path => '.' }
|
||||
s.source_files = 'Classes/**/*'
|
||||
s.dependency 'Flutter'
|
||||
s.platform = :ios, '9.0'
|
||||
s.platform = :ios, '11.0'
|
||||
|
||||
# Flutter.framework does not contain a i386 slice.
|
||||
s.pod_target_xcconfig = { 'DEFINES_MODULE' => 'YES', 'EXCLUDED_ARCHS[sdk=iphonesimulator*]' => 'i386' }
|
@ -483,12 +483,12 @@ class MyCentralControllerHostApi {
|
||||
}
|
||||
}
|
||||
|
||||
Future<Uint8List> readCharacteristic(int arg_myPeripheralKey, int arg_myCharacteristicKey) async {
|
||||
Future<Uint8List> readCharacteristic(int arg_myPeripheralKey, int arg_myServiceKey, int arg_myCharacteristicKey) async {
|
||||
final BasicMessageChannel<Object?> channel = BasicMessageChannel<Object?>(
|
||||
'dev.flutter.pigeon.bluetooth_low_energy_ios.MyCentralControllerHostApi.readCharacteristic', codec,
|
||||
binaryMessenger: _binaryMessenger);
|
||||
final List<Object?>? replyList =
|
||||
await channel.send(<Object?>[arg_myPeripheralKey, arg_myCharacteristicKey]) as List<Object?>?;
|
||||
await channel.send(<Object?>[arg_myPeripheralKey, arg_myServiceKey, arg_myCharacteristicKey]) as List<Object?>?;
|
||||
if (replyList == null) {
|
||||
throw PlatformException(
|
||||
code: 'channel-error',
|
||||
@ -510,12 +510,12 @@ class MyCentralControllerHostApi {
|
||||
}
|
||||
}
|
||||
|
||||
Future<void> writeCharacteristic(int arg_myPeripheralKey, int arg_myCharacteristicKey, Uint8List arg_value, int arg_myTypeNumber) async {
|
||||
Future<void> writeCharacteristic(int arg_myPeripheralKey, int arg_myServiceKey, int arg_myCharacteristicKey, Uint8List arg_value, int arg_myTypeNumber) async {
|
||||
final BasicMessageChannel<Object?> channel = BasicMessageChannel<Object?>(
|
||||
'dev.flutter.pigeon.bluetooth_low_energy_ios.MyCentralControllerHostApi.writeCharacteristic', codec,
|
||||
binaryMessenger: _binaryMessenger);
|
||||
final List<Object?>? replyList =
|
||||
await channel.send(<Object?>[arg_myPeripheralKey, arg_myCharacteristicKey, arg_value, arg_myTypeNumber]) as List<Object?>?;
|
||||
await channel.send(<Object?>[arg_myPeripheralKey, arg_myServiceKey, arg_myCharacteristicKey, arg_value, arg_myTypeNumber]) as List<Object?>?;
|
||||
if (replyList == null) {
|
||||
throw PlatformException(
|
||||
code: 'channel-error',
|
||||
@ -532,12 +532,12 @@ class MyCentralControllerHostApi {
|
||||
}
|
||||
}
|
||||
|
||||
Future<void> notifyCharacteristic(int arg_myPeripheralKey, int arg_myCharacteristicKey, bool arg_state) async {
|
||||
Future<void> notifyCharacteristic(int arg_myPeripheralKey, int arg_myServiceKey, int arg_myCharacteristicKey, bool arg_state) async {
|
||||
final BasicMessageChannel<Object?> channel = BasicMessageChannel<Object?>(
|
||||
'dev.flutter.pigeon.bluetooth_low_energy_ios.MyCentralControllerHostApi.notifyCharacteristic', codec,
|
||||
binaryMessenger: _binaryMessenger);
|
||||
final List<Object?>? replyList =
|
||||
await channel.send(<Object?>[arg_myPeripheralKey, arg_myCharacteristicKey, arg_state]) as List<Object?>?;
|
||||
await channel.send(<Object?>[arg_myPeripheralKey, arg_myServiceKey, arg_myCharacteristicKey, arg_state]) as List<Object?>?;
|
||||
if (replyList == null) {
|
||||
throw PlatformException(
|
||||
code: 'channel-error',
|
||||
@ -554,12 +554,12 @@ class MyCentralControllerHostApi {
|
||||
}
|
||||
}
|
||||
|
||||
Future<Uint8List> readDescriptor(int arg_myPeripheralKey, int arg_myDescriptorKey) async {
|
||||
Future<Uint8List> readDescriptor(int arg_myPeripheralKey, int arg_myCharacteristicKey, int arg_myDescriptorKey) async {
|
||||
final BasicMessageChannel<Object?> channel = BasicMessageChannel<Object?>(
|
||||
'dev.flutter.pigeon.bluetooth_low_energy_ios.MyCentralControllerHostApi.readDescriptor', codec,
|
||||
binaryMessenger: _binaryMessenger);
|
||||
final List<Object?>? replyList =
|
||||
await channel.send(<Object?>[arg_myPeripheralKey, arg_myDescriptorKey]) as List<Object?>?;
|
||||
await channel.send(<Object?>[arg_myPeripheralKey, arg_myCharacteristicKey, arg_myDescriptorKey]) as List<Object?>?;
|
||||
if (replyList == null) {
|
||||
throw PlatformException(
|
||||
code: 'channel-error',
|
||||
@ -581,12 +581,12 @@ class MyCentralControllerHostApi {
|
||||
}
|
||||
}
|
||||
|
||||
Future<void> writeDescriptor(int arg_myPeripheralKey, int arg_myDescriptorKey, Uint8List arg_value) async {
|
||||
Future<void> writeDescriptor(int arg_myPeripheralKey, int arg_myCharacteristicKey, int arg_myDescriptorKey, Uint8List arg_value) async {
|
||||
final BasicMessageChannel<Object?> channel = BasicMessageChannel<Object?>(
|
||||
'dev.flutter.pigeon.bluetooth_low_energy_ios.MyCentralControllerHostApi.writeDescriptor', codec,
|
||||
binaryMessenger: _binaryMessenger);
|
||||
final List<Object?>? replyList =
|
||||
await channel.send(<Object?>[arg_myPeripheralKey, arg_myDescriptorKey, arg_value]) as List<Object?>?;
|
||||
await channel.send(<Object?>[arg_myPeripheralKey, arg_myCharacteristicKey, arg_myDescriptorKey, arg_value]) as List<Object?>?;
|
||||
if (replyList == null) {
|
||||
throw PlatformException(
|
||||
code: 'channel-error',
|
||||
|
@ -126,18 +126,16 @@ class MyCentralController extends CentralController
|
||||
await _throwWithoutState(CentralState.poweredOn);
|
||||
final myPeripheral = peripheral as MyPeripheral;
|
||||
final myServiceArgses = await _myApi.getServices(myPeripheral.hashCode);
|
||||
return myServiceArgses
|
||||
.cast<MyGattServiceArgs>()
|
||||
.map(
|
||||
(myServiceArgs) => _myServices.putIfAbsent(
|
||||
myServiceArgs.key,
|
||||
() => MyGattService.fromMyArgs(
|
||||
myPeripheral,
|
||||
myServiceArgs,
|
||||
),
|
||||
),
|
||||
)
|
||||
.toList();
|
||||
return myServiceArgses.cast<MyGattServiceArgs>().map(
|
||||
(myServiceArgs) {
|
||||
final myService = MyGattService.fromMyArgs(
|
||||
myPeripheral,
|
||||
myServiceArgs,
|
||||
);
|
||||
_myServices[myService.hashCode] = myService;
|
||||
return myService;
|
||||
},
|
||||
).toList();
|
||||
}
|
||||
|
||||
@override
|
||||
@ -149,18 +147,16 @@ class MyCentralController extends CentralController
|
||||
final myCharactersiticArgses = await _myApi.getCharacteristics(
|
||||
myService.hashCode,
|
||||
);
|
||||
return myCharactersiticArgses
|
||||
.cast<MyGattCharacteristicArgs>()
|
||||
.map(
|
||||
(myCharacteristicArgs) => _myCharacteristics.putIfAbsent(
|
||||
myCharacteristicArgs.key,
|
||||
() => MyGattCharacteristic.fromMyArgs(
|
||||
myService,
|
||||
myCharacteristicArgs,
|
||||
),
|
||||
),
|
||||
)
|
||||
.toList();
|
||||
return myCharactersiticArgses.cast<MyGattCharacteristicArgs>().map(
|
||||
(myCharacteristicArgs) {
|
||||
final myCharacteristic = MyGattCharacteristic.fromMyArgs(
|
||||
myService,
|
||||
myCharacteristicArgs,
|
||||
);
|
||||
_myCharacteristics[myCharacteristic.hashCode] = myCharacteristic;
|
||||
return myCharacteristic;
|
||||
},
|
||||
).toList();
|
||||
}
|
||||
|
||||
@override
|
||||
@ -172,18 +168,16 @@ class MyCentralController extends CentralController
|
||||
final myDescriptorArgses = await _myApi.getDescriptors(
|
||||
myCharacteristic.hashCode,
|
||||
);
|
||||
return myDescriptorArgses
|
||||
.cast<MyGattDescriptorArgs>()
|
||||
.map(
|
||||
(myDescriptorArgs) => _myDescriptors.putIfAbsent(
|
||||
myDescriptorArgs.key,
|
||||
() => MyGattDescriptor.fromMyArgs(
|
||||
myCharacteristic,
|
||||
myDescriptorArgs,
|
||||
),
|
||||
),
|
||||
)
|
||||
.toList();
|
||||
return myDescriptorArgses.cast<MyGattDescriptorArgs>().map(
|
||||
(myDescriptorArgs) {
|
||||
final myDescriptor = MyGattDescriptor.fromMyArgs(
|
||||
myCharacteristic,
|
||||
myDescriptorArgs,
|
||||
);
|
||||
_myDescriptors[myDescriptor.hashCode] = myDescriptor;
|
||||
return myDescriptor;
|
||||
},
|
||||
).toList();
|
||||
}
|
||||
|
||||
@override
|
||||
@ -196,6 +190,7 @@ class MyCentralController extends CentralController
|
||||
final myPeripheral = myService.myPeripheral;
|
||||
final value = await _myApi.readCharacteristic(
|
||||
myPeripheral.hashCode,
|
||||
myService.hashCode,
|
||||
myCharacteristic.hashCode,
|
||||
);
|
||||
return value;
|
||||
@ -215,6 +210,7 @@ class MyCentralController extends CentralController
|
||||
final typeNumber = typeArgs.index;
|
||||
await _myApi.writeCharacteristic(
|
||||
myPeripheral.hashCode,
|
||||
myService.hashCode,
|
||||
myCharacteristic.hashCode,
|
||||
value,
|
||||
typeNumber,
|
||||
@ -232,6 +228,7 @@ class MyCentralController extends CentralController
|
||||
final myPeripheral = myService.myPeripheral;
|
||||
await _myApi.notifyCharacteristic(
|
||||
myPeripheral.hashCode,
|
||||
myService.hashCode,
|
||||
myCharacteristic.hashCode,
|
||||
state,
|
||||
);
|
||||
@ -246,6 +243,7 @@ class MyCentralController extends CentralController
|
||||
final myPeripheral = myService.myPeripheral;
|
||||
final value = await _myApi.readDescriptor(
|
||||
myPeripheral.hashCode,
|
||||
myCharacteristic.hashCode,
|
||||
myDescriptor.hashCode,
|
||||
);
|
||||
return value;
|
||||
@ -263,6 +261,7 @@ class MyCentralController extends CentralController
|
||||
final myPeripheral = myService.myPeripheral;
|
||||
await _myApi.writeDescriptor(
|
||||
myPeripheral.hashCode,
|
||||
myCharacteristic.hashCode,
|
||||
myDescriptor.hashCode,
|
||||
value,
|
||||
);
|
||||
@ -286,10 +285,8 @@ class MyCentralController extends CentralController
|
||||
int rssi,
|
||||
MyAdvertisementArgs myAdvertisementArgs,
|
||||
) {
|
||||
final myPeripheral = _myPeripherals.putIfAbsent(
|
||||
myPeripheralArgs.key,
|
||||
() => MyPeripheral.fromMyArgs(myPeripheralArgs),
|
||||
);
|
||||
final myPeripheral = MyPeripheral.fromMyArgs(myPeripheralArgs);
|
||||
_myPeripherals[myPeripheral.hashCode] = myPeripheral;
|
||||
final advertisement = myAdvertisementArgs.toAdvertisement();
|
||||
final eventArgs = CentralDiscoveredEventArgs(
|
||||
myPeripheral,
|
||||
|
@ -25,10 +25,15 @@ abstract class MyCentralControllerHostApi {
|
||||
List<MyGattCharacteristicArgs> getCharacteristics(int myServiceKey);
|
||||
List<MyGattDescriptorArgs> getDescriptors(int myCharacteristicKey);
|
||||
@async
|
||||
Uint8List readCharacteristic(int myPeripheralKey, int myCharacteristicKey);
|
||||
Uint8List readCharacteristic(
|
||||
int myPeripheralKey,
|
||||
int myServiceKey,
|
||||
int myCharacteristicKey,
|
||||
);
|
||||
@async
|
||||
void writeCharacteristic(
|
||||
int myPeripheralKey,
|
||||
int myServiceKey,
|
||||
int myCharacteristicKey,
|
||||
Uint8List value,
|
||||
int myTypeNumber,
|
||||
@ -36,14 +41,20 @@ abstract class MyCentralControllerHostApi {
|
||||
@async
|
||||
void notifyCharacteristic(
|
||||
int myPeripheralKey,
|
||||
int myServiceKey,
|
||||
int myCharacteristicKey,
|
||||
bool state,
|
||||
);
|
||||
@async
|
||||
Uint8List readDescriptor(int myPeripheralKey, int myDescriptorKey);
|
||||
Uint8List readDescriptor(
|
||||
int myPeripheralKey,
|
||||
int myCharacteristicKey,
|
||||
int myDescriptorKey,
|
||||
);
|
||||
@async
|
||||
void writeDescriptor(
|
||||
int myPeripheralKey,
|
||||
int myCharacteristicKey,
|
||||
int myDescriptorKey,
|
||||
Uint8List value,
|
||||
);
|
||||
|
@ -1,6 +1,6 @@
|
||||
name: bluetooth_low_energy_ios
|
||||
description: iOS implementation of the bluetooth_low_energy plugin.
|
||||
version: 2.0.0
|
||||
version: 2.0.1
|
||||
homepage: https://github.com/yanshouwang/bluetooth_low_energy
|
||||
|
||||
environment:
|
||||
@ -10,7 +10,7 @@ environment:
|
||||
dependencies:
|
||||
flutter:
|
||||
sdk: flutter
|
||||
bluetooth_low_energy_platform_interface: ^2.0.0
|
||||
bluetooth_low_energy_platform_interface: ^2.0.1
|
||||
|
||||
dev_dependencies:
|
||||
flutter_test:
|
||||
|
Reference in New Issue
Block a user