* fix: 重构

* fix: 1

* fix: 重构

* fix: 修复 iOS 和 macOS 代码错误

* fix: 优化项目

* fix: 构建项目

* fix: 修复权限问题

* fix: 解决 macOS 沙盒权限问题

* fix: 修复代码问题

* fix: 更新依赖

* fix: 更新依赖项

* fix: 添加缺失的位置权限
This commit is contained in:
Mr剑侠客
2023-08-21 01:06:57 +08:00
committed by GitHub
parent 689b1fb045
commit 0f4fb7f553
127 changed files with 560 additions and 3693 deletions

30
bluetooth_low_energy_darwin/.gitignore vendored Normal file
View File

@ -0,0 +1,30 @@
# Miscellaneous
*.class
*.log
*.pyc
*.swp
.DS_Store
.atom/
.buildlog/
.history
.svn/
migrate_working_dir/
# IntelliJ related
*.iml
*.ipr
*.iws
.idea/
# The .vscode folder contains launch configuration and tasks you configure in
# VS Code which you may wish to be included in version control, so this line
# is commented out by default.
#.vscode/
# Flutter/Dart/Pub related
# Libraries should not include pubspec.lock, per https://dart.dev/guides/libraries/private-files#pubspeclock.
/pubspec.lock
**/doc/api/
.dart_tool/
.packages
build/

View File

@ -0,0 +1,33 @@
# This file tracks properties of this Flutter project.
# Used by Flutter tool to assess capabilities and perform upgrades etc.
#
# This file should be version controlled and should not be manually edited.
version:
revision: "efbf63d9c66b9f6ec30e9ad4611189aa80003d31"
channel: "stable"
project_type: plugin
# Tracks metadata for the flutter migrate command
migration:
platforms:
- platform: root
create_revision: efbf63d9c66b9f6ec30e9ad4611189aa80003d31
base_revision: efbf63d9c66b9f6ec30e9ad4611189aa80003d31
- platform: ios
create_revision: efbf63d9c66b9f6ec30e9ad4611189aa80003d31
base_revision: efbf63d9c66b9f6ec30e9ad4611189aa80003d31
- platform: macos
create_revision: efbf63d9c66b9f6ec30e9ad4611189aa80003d31
base_revision: efbf63d9c66b9f6ec30e9ad4611189aa80003d31
# User provided section
# List of Local paths (relative to this file) that should be
# ignored by the migrate tool.
#
# Files that are not part of the templates will be ignored by default.
unmanaged_files:
- 'lib/main.dart'
- 'ios/Runner.xcodeproj/project.pbxproj'

View File

@ -0,0 +1,4 @@
## 2.0.2
- Combine iOS and macOS projects.
- Optimize project structure.

View File

@ -0,0 +1,21 @@
MIT License
Copyright (c) 2021 yanshouwang
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

View File

@ -0,0 +1,15 @@
# bluetooth_low_energy_darwin
The iOS and macOS implementation of [`bluetooth_low_energy`][1].
## Usage
This package is [endorsed][2], which means you can simply use `bluetooth_low_energy`
normally. This package will be automatically included in your app when you do,
so you do not need to add it to your `pubspec.yaml`.
However, if you `import` this package to use any of its APIs directly, you
should add it to your `pubspec.yaml` as usual.
[1]: https://pub.dev/packages/bluetooth_low_energy
[2]: https://flutter.dev/docs/development/packages-and-plugins/developing-packages#endorsed-federated-plugin

View File

@ -0,0 +1,4 @@
include: package:flutter_lints/flutter.yaml
# Additional information about this file can be found at
# https://dart.dev/guides/language/analysis-options

View File

@ -0,0 +1,23 @@
#if os(iOS)
import Flutter
import UIKit
#elseif os(macOS)
import Cocoa
import FlutterMacOS
#else
#error("Unsupported platform.")
#endif
public class BluetoothLowEnergyDarwin: NSObject, FlutterPlugin {
public static func register(with registrar: FlutterPluginRegistrar) {
#if os(iOS)
let binaryMessenger = registrar.messenger()
#elseif os(macOS)
let binaryMessenger = registrar.messenger
#else
#error("Unsupported platform.")
#endif
let centralController = MyCentralController(binaryMessenger)
MyCentralControllerHostApiSetup.setUp(binaryMessenger: binaryMessenger, api: centralController)
}
}

View File

@ -0,0 +1,599 @@
// Autogenerated from Pigeon (v10.1.6), do not edit directly.
// See also: https://pub.dev/packages/pigeon
import Foundation
#if os(iOS)
import Flutter
#elseif os(macOS)
import FlutterMacOS
#else
#error("Unsupported platform.")
#endif
private func wrapResult(_ result: Any?) -> [Any?] {
return [result]
}
private func wrapError(_ error: Any) -> [Any?] {
if let flutterError = error as? FlutterError {
return [
flutterError.code,
flutterError.message,
flutterError.details
]
}
return [
"\(error)",
"\(type(of: error))",
"Stacktrace: \(Thread.callStackSymbols)"
]
}
private func nilOrValue<T>(_ value: Any?) -> T? {
if value is NSNull { return nil }
return value as! T?
}
enum MyCentralStateArgs: Int {
case unknown = 0
case unsupported = 1
case unauthorized = 2
case poweredOff = 3
case poweredOn = 4
}
enum MyGattCharacteristicPropertyArgs: Int {
case read = 0
case write = 1
case writeWithoutResponse = 2
case notify = 3
case indicate = 4
}
enum MyGattCharacteristicWriteTypeArgs: Int {
case withResponse = 0
case withoutResponse = 1
}
/// Generated class from Pigeon that represents data sent in messages.
struct MyCentralControllerArgs {
var myStateNumber: Int64
static func fromList(_ list: [Any?]) -> MyCentralControllerArgs? {
let myStateNumber = list[0] is Int64 ? list[0] as! Int64 : Int64(list[0] as! Int32)
return MyCentralControllerArgs(
myStateNumber: myStateNumber
)
}
func toList() -> [Any?] {
return [
myStateNumber,
]
}
}
/// Generated class from Pigeon that represents data sent in messages.
struct MyPeripheralArgs {
var key: Int64
var uuid: String
static func fromList(_ list: [Any?]) -> MyPeripheralArgs? {
let key = list[0] is Int64 ? list[0] as! Int64 : Int64(list[0] as! Int32)
let uuid = list[1] as! String
return MyPeripheralArgs(
key: key,
uuid: uuid
)
}
func toList() -> [Any?] {
return [
key,
uuid,
]
}
}
/// Generated class from Pigeon that represents data sent in messages.
struct MyAdvertisementArgs {
var name: String? = nil
var manufacturerSpecificData: [Int64?: FlutterStandardTypedData?]
var serviceUUIDs: [String?]
var serviceData: [String?: FlutterStandardTypedData?]
static func fromList(_ list: [Any?]) -> MyAdvertisementArgs? {
let name: String? = nilOrValue(list[0])
let manufacturerSpecificData = list[1] as! [Int64?: FlutterStandardTypedData?]
let serviceUUIDs = list[2] as! [String?]
let serviceData = list[3] as! [String?: FlutterStandardTypedData?]
return MyAdvertisementArgs(
name: name,
manufacturerSpecificData: manufacturerSpecificData,
serviceUUIDs: serviceUUIDs,
serviceData: serviceData
)
}
func toList() -> [Any?] {
return [
name,
manufacturerSpecificData,
serviceUUIDs,
serviceData,
]
}
}
/// Generated class from Pigeon that represents data sent in messages.
struct MyGattServiceArgs {
var key: Int64
var uuid: String
static func fromList(_ list: [Any?]) -> MyGattServiceArgs? {
let key = list[0] is Int64 ? list[0] as! Int64 : Int64(list[0] as! Int32)
let uuid = list[1] as! String
return MyGattServiceArgs(
key: key,
uuid: uuid
)
}
func toList() -> [Any?] {
return [
key,
uuid,
]
}
}
/// Generated class from Pigeon that represents data sent in messages.
struct MyGattCharacteristicArgs {
var key: Int64
var uuid: String
var myPropertyNumbers: [Int64?]
static func fromList(_ list: [Any?]) -> MyGattCharacteristicArgs? {
let key = list[0] is Int64 ? list[0] as! Int64 : Int64(list[0] as! Int32)
let uuid = list[1] as! String
let myPropertyNumbers = list[2] as! [Int64?]
return MyGattCharacteristicArgs(
key: key,
uuid: uuid,
myPropertyNumbers: myPropertyNumbers
)
}
func toList() -> [Any?] {
return [
key,
uuid,
myPropertyNumbers,
]
}
}
/// Generated class from Pigeon that represents data sent in messages.
struct MyGattDescriptorArgs {
var key: Int64
var uuid: String
static func fromList(_ list: [Any?]) -> MyGattDescriptorArgs? {
let key = list[0] is Int64 ? list[0] as! Int64 : Int64(list[0] as! Int32)
let uuid = list[1] as! String
return MyGattDescriptorArgs(
key: key,
uuid: uuid
)
}
func toList() -> [Any?] {
return [
key,
uuid,
]
}
}
private class MyCentralControllerHostApiCodecReader: FlutterStandardReader {
override func readValue(ofType type: UInt8) -> Any? {
switch type {
case 128:
return MyCentralControllerArgs.fromList(self.readValue() as! [Any?])
case 129:
return MyGattCharacteristicArgs.fromList(self.readValue() as! [Any?])
case 130:
return MyGattDescriptorArgs.fromList(self.readValue() as! [Any?])
case 131:
return MyGattServiceArgs.fromList(self.readValue() as! [Any?])
default:
return super.readValue(ofType: type)
}
}
}
private class MyCentralControllerHostApiCodecWriter: FlutterStandardWriter {
override func writeValue(_ value: Any) {
if let value = value as? MyCentralControllerArgs {
super.writeByte(128)
super.writeValue(value.toList())
} else if let value = value as? MyGattCharacteristicArgs {
super.writeByte(129)
super.writeValue(value.toList())
} else if let value = value as? MyGattDescriptorArgs {
super.writeByte(130)
super.writeValue(value.toList())
} else if let value = value as? MyGattServiceArgs {
super.writeByte(131)
super.writeValue(value.toList())
} else {
super.writeValue(value)
}
}
}
private class MyCentralControllerHostApiCodecReaderWriter: FlutterStandardReaderWriter {
override func reader(with data: Data) -> FlutterStandardReader {
return MyCentralControllerHostApiCodecReader(data: data)
}
override func writer(with data: NSMutableData) -> FlutterStandardWriter {
return MyCentralControllerHostApiCodecWriter(data: data)
}
}
class MyCentralControllerHostApiCodec: FlutterStandardMessageCodec {
static let shared = MyCentralControllerHostApiCodec(readerWriter: MyCentralControllerHostApiCodecReaderWriter())
}
/// Generated protocol from Pigeon that represents a handler of messages from Flutter.
protocol MyCentralControllerHostApi {
func setUp(completion: @escaping (Result<MyCentralControllerArgs, Error>) -> Void)
func tearDown() throws
func startDiscovery() throws
func stopDiscovery() throws
func connect(myPeripheralKey: Int64, completion: @escaping (Result<Void, Error>) -> Void)
func disconnect(myPeripheralKey: Int64, completion: @escaping (Result<Void, Error>) -> Void)
func discoverGATT(myPeripheralKey: Int64, completion: @escaping (Result<Void, Error>) -> Void)
func getServices(myPeripheralKey: Int64) throws -> [MyGattServiceArgs]
func getCharacteristics(myServiceKey: Int64) throws -> [MyGattCharacteristicArgs]
func getDescriptors(myCharacteristicKey: Int64) throws -> [MyGattDescriptorArgs]
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`.
class MyCentralControllerHostApiSetup {
/// The codec used by MyCentralControllerHostApi.
static var codec: FlutterStandardMessageCodec { MyCentralControllerHostApiCodec.shared }
/// Sets up an instance of `MyCentralControllerHostApi` to handle messages through the `binaryMessenger`.
static func setUp(binaryMessenger: FlutterBinaryMessenger, api: MyCentralControllerHostApi?) {
let setUpChannel = FlutterBasicMessageChannel(name: "dev.flutter.pigeon.bluetooth_low_energy_darwin.MyCentralControllerHostApi.setUp", binaryMessenger: binaryMessenger, codec: codec)
if let api = api {
setUpChannel.setMessageHandler { _, reply in
api.setUp() { result in
switch result {
case .success(let res):
reply(wrapResult(res))
case .failure(let error):
reply(wrapError(error))
}
}
}
} else {
setUpChannel.setMessageHandler(nil)
}
let tearDownChannel = FlutterBasicMessageChannel(name: "dev.flutter.pigeon.bluetooth_low_energy_darwin.MyCentralControllerHostApi.tearDown", binaryMessenger: binaryMessenger, codec: codec)
if let api = api {
tearDownChannel.setMessageHandler { _, reply in
do {
try api.tearDown()
reply(wrapResult(nil))
} catch {
reply(wrapError(error))
}
}
} else {
tearDownChannel.setMessageHandler(nil)
}
let startDiscoveryChannel = FlutterBasicMessageChannel(name: "dev.flutter.pigeon.bluetooth_low_energy_darwin.MyCentralControllerHostApi.startDiscovery", binaryMessenger: binaryMessenger, codec: codec)
if let api = api {
startDiscoveryChannel.setMessageHandler { _, reply in
do {
try api.startDiscovery()
reply(wrapResult(nil))
} catch {
reply(wrapError(error))
}
}
} else {
startDiscoveryChannel.setMessageHandler(nil)
}
let stopDiscoveryChannel = FlutterBasicMessageChannel(name: "dev.flutter.pigeon.bluetooth_low_energy_darwin.MyCentralControllerHostApi.stopDiscovery", binaryMessenger: binaryMessenger, codec: codec)
if let api = api {
stopDiscoveryChannel.setMessageHandler { _, reply in
do {
try api.stopDiscovery()
reply(wrapResult(nil))
} catch {
reply(wrapError(error))
}
}
} else {
stopDiscoveryChannel.setMessageHandler(nil)
}
let connectChannel = FlutterBasicMessageChannel(name: "dev.flutter.pigeon.bluetooth_low_energy_darwin.MyCentralControllerHostApi.connect", binaryMessenger: binaryMessenger, codec: codec)
if let api = api {
connectChannel.setMessageHandler { message, reply in
let args = message as! [Any?]
let myPeripheralKeyArg = args[0] is Int64 ? args[0] as! Int64 : Int64(args[0] as! Int32)
api.connect(myPeripheralKey: myPeripheralKeyArg) { result in
switch result {
case .success:
reply(wrapResult(nil))
case .failure(let error):
reply(wrapError(error))
}
}
}
} else {
connectChannel.setMessageHandler(nil)
}
let disconnectChannel = FlutterBasicMessageChannel(name: "dev.flutter.pigeon.bluetooth_low_energy_darwin.MyCentralControllerHostApi.disconnect", binaryMessenger: binaryMessenger, codec: codec)
if let api = api {
disconnectChannel.setMessageHandler { message, reply in
let args = message as! [Any?]
let myPeripheralKeyArg = args[0] is Int64 ? args[0] as! Int64 : Int64(args[0] as! Int32)
api.disconnect(myPeripheralKey: myPeripheralKeyArg) { result in
switch result {
case .success:
reply(wrapResult(nil))
case .failure(let error):
reply(wrapError(error))
}
}
}
} else {
disconnectChannel.setMessageHandler(nil)
}
let discoverGATTChannel = FlutterBasicMessageChannel(name: "dev.flutter.pigeon.bluetooth_low_energy_darwin.MyCentralControllerHostApi.discoverGATT", binaryMessenger: binaryMessenger, codec: codec)
if let api = api {
discoverGATTChannel.setMessageHandler { message, reply in
let args = message as! [Any?]
let myPeripheralKeyArg = args[0] is Int64 ? args[0] as! Int64 : Int64(args[0] as! Int32)
api.discoverGATT(myPeripheralKey: myPeripheralKeyArg) { result in
switch result {
case .success:
reply(wrapResult(nil))
case .failure(let error):
reply(wrapError(error))
}
}
}
} else {
discoverGATTChannel.setMessageHandler(nil)
}
let getServicesChannel = FlutterBasicMessageChannel(name: "dev.flutter.pigeon.bluetooth_low_energy_darwin.MyCentralControllerHostApi.getServices", binaryMessenger: binaryMessenger, codec: codec)
if let api = api {
getServicesChannel.setMessageHandler { message, reply in
let args = message as! [Any?]
let myPeripheralKeyArg = args[0] is Int64 ? args[0] as! Int64 : Int64(args[0] as! Int32)
do {
let result = try api.getServices(myPeripheralKey: myPeripheralKeyArg)
reply(wrapResult(result))
} catch {
reply(wrapError(error))
}
}
} else {
getServicesChannel.setMessageHandler(nil)
}
let getCharacteristicsChannel = FlutterBasicMessageChannel(name: "dev.flutter.pigeon.bluetooth_low_energy_darwin.MyCentralControllerHostApi.getCharacteristics", binaryMessenger: binaryMessenger, codec: codec)
if let api = api {
getCharacteristicsChannel.setMessageHandler { message, reply in
let args = message as! [Any?]
let myServiceKeyArg = args[0] is Int64 ? args[0] as! Int64 : Int64(args[0] as! Int32)
do {
let result = try api.getCharacteristics(myServiceKey: myServiceKeyArg)
reply(wrapResult(result))
} catch {
reply(wrapError(error))
}
}
} else {
getCharacteristicsChannel.setMessageHandler(nil)
}
let getDescriptorsChannel = FlutterBasicMessageChannel(name: "dev.flutter.pigeon.bluetooth_low_energy_darwin.MyCentralControllerHostApi.getDescriptors", binaryMessenger: binaryMessenger, codec: codec)
if let api = api {
getDescriptorsChannel.setMessageHandler { message, reply in
let args = message as! [Any?]
let myCharacteristicKeyArg = args[0] is Int64 ? args[0] as! Int64 : Int64(args[0] as! Int32)
do {
let result = try api.getDescriptors(myCharacteristicKey: myCharacteristicKeyArg)
reply(wrapResult(result))
} catch {
reply(wrapError(error))
}
}
} else {
getDescriptorsChannel.setMessageHandler(nil)
}
let readCharacteristicChannel = FlutterBasicMessageChannel(name: "dev.flutter.pigeon.bluetooth_low_energy_darwin.MyCentralControllerHostApi.readCharacteristic", binaryMessenger: binaryMessenger, codec: codec)
if let api = api {
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 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))
case .failure(let error):
reply(wrapError(error))
}
}
}
} else {
readCharacteristicChannel.setMessageHandler(nil)
}
let writeCharacteristicChannel = FlutterBasicMessageChannel(name: "dev.flutter.pigeon.bluetooth_low_energy_darwin.MyCentralControllerHostApi.writeCharacteristic", binaryMessenger: binaryMessenger, codec: codec)
if let api = api {
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 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))
case .failure(let error):
reply(wrapError(error))
}
}
}
} else {
writeCharacteristicChannel.setMessageHandler(nil)
}
let notifyCharacteristicChannel = FlutterBasicMessageChannel(name: "dev.flutter.pigeon.bluetooth_low_energy_darwin.MyCentralControllerHostApi.notifyCharacteristic", binaryMessenger: binaryMessenger, codec: codec)
if let api = api {
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 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))
case .failure(let error):
reply(wrapError(error))
}
}
}
} else {
notifyCharacteristicChannel.setMessageHandler(nil)
}
let readDescriptorChannel = FlutterBasicMessageChannel(name: "dev.flutter.pigeon.bluetooth_low_energy_darwin.MyCentralControllerHostApi.readDescriptor", binaryMessenger: binaryMessenger, codec: codec)
if let api = api {
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 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))
case .failure(let error):
reply(wrapError(error))
}
}
}
} else {
readDescriptorChannel.setMessageHandler(nil)
}
let writeDescriptorChannel = FlutterBasicMessageChannel(name: "dev.flutter.pigeon.bluetooth_low_energy_darwin.MyCentralControllerHostApi.writeDescriptor", binaryMessenger: binaryMessenger, codec: codec)
if let api = api {
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 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))
case .failure(let error):
reply(wrapError(error))
}
}
}
} else {
writeDescriptorChannel.setMessageHandler(nil)
}
}
}
private class MyCentralControllerFlutterApiCodecReader: FlutterStandardReader {
override func readValue(ofType type: UInt8) -> Any? {
switch type {
case 128:
return MyAdvertisementArgs.fromList(self.readValue() as! [Any?])
case 129:
return MyPeripheralArgs.fromList(self.readValue() as! [Any?])
default:
return super.readValue(ofType: type)
}
}
}
private class MyCentralControllerFlutterApiCodecWriter: FlutterStandardWriter {
override func writeValue(_ value: Any) {
if let value = value as? MyAdvertisementArgs {
super.writeByte(128)
super.writeValue(value.toList())
} else if let value = value as? MyPeripheralArgs {
super.writeByte(129)
super.writeValue(value.toList())
} else {
super.writeValue(value)
}
}
}
private class MyCentralControllerFlutterApiCodecReaderWriter: FlutterStandardReaderWriter {
override func reader(with data: Data) -> FlutterStandardReader {
return MyCentralControllerFlutterApiCodecReader(data: data)
}
override func writer(with data: NSMutableData) -> FlutterStandardWriter {
return MyCentralControllerFlutterApiCodecWriter(data: data)
}
}
class MyCentralControllerFlutterApiCodec: FlutterStandardMessageCodec {
static let shared = MyCentralControllerFlutterApiCodec(readerWriter: MyCentralControllerFlutterApiCodecReaderWriter())
}
/// Generated class from Pigeon that represents Flutter messages that can be called from Swift.
class MyCentralControllerFlutterApi {
private let binaryMessenger: FlutterBinaryMessenger
init(binaryMessenger: FlutterBinaryMessenger){
self.binaryMessenger = binaryMessenger
}
var codec: FlutterStandardMessageCodec {
return MyCentralControllerFlutterApiCodec.shared
}
func onStateChanged(myStateNumber myStateNumberArg: Int64, completion: @escaping () -> Void) {
let channel = FlutterBasicMessageChannel(name: "dev.flutter.pigeon.bluetooth_low_energy_darwin.MyCentralControllerFlutterApi.onStateChanged", binaryMessenger: binaryMessenger, codec: codec)
channel.sendMessage([myStateNumberArg] as [Any?]) { _ in
completion()
}
}
func onDiscovered(myPeripheralArgs myPeripheralArgsArg: MyPeripheralArgs, rssi rssiArg: Int64, myAdvertisementArgs myAdvertisementArgsArg: MyAdvertisementArgs, completion: @escaping () -> Void) {
let channel = FlutterBasicMessageChannel(name: "dev.flutter.pigeon.bluetooth_low_energy_darwin.MyCentralControllerFlutterApi.onDiscovered", binaryMessenger: binaryMessenger, codec: codec)
channel.sendMessage([myPeripheralArgsArg, rssiArg, myAdvertisementArgsArg] as [Any?]) { _ in
completion()
}
}
func onPeripheralStateChanged(myPeripheralKey myPeripheralKeyArg: Int64, state stateArg: Bool, completion: @escaping () -> Void) {
let channel = FlutterBasicMessageChannel(name: "dev.flutter.pigeon.bluetooth_low_energy_darwin.MyCentralControllerFlutterApi.onPeripheralStateChanged", binaryMessenger: binaryMessenger, codec: codec)
channel.sendMessage([myPeripheralKeyArg, stateArg] as [Any?]) { _ in
completion()
}
}
func onCharacteristicValueChanged(myCharacteristicKey myCharacteristicKeyArg: Int64, value valueArg: FlutterStandardTypedData, completion: @escaping () -> Void) {
let channel = FlutterBasicMessageChannel(name: "dev.flutter.pigeon.bluetooth_low_energy_darwin.MyCentralControllerFlutterApi.onCharacteristicValueChanged", binaryMessenger: binaryMessenger, codec: codec)
channel.sendMessage([myCharacteristicKeyArg, valueArg] as [Any?]) { _ in
completion()
}
}
}

View File

@ -0,0 +1,722 @@
//
// 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 MyCentralController: MyCentralControllerHostApi {
init(_ binaryMessenger: FlutterBinaryMessenger) {
myApi = MyCentralControllerFlutterApi(binaryMessenger: binaryMessenger)
}
private let myApi: MyCentralControllerFlutterApi
private lazy var myCentralManagerDelegate = MyCentralManagerDelegate(self)
private lazy var myPeripheralDelegate = MyPeripheralDelegate(self)
private let centralManager = CBCentralManager()
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]()
var disconnectCompletions = [Int: (Result<Void, Error>) -> Void]()
var discoverGattCompletions = [Int: (Result<Void, Error>) -> Void]()
var unfinishedServices = [Int: [CBService]]()
var unfinishedCharacteristics = [Int: [CBCharacteristic]]()
var readCharacteristicCompletions = [Int: (Result<FlutterStandardTypedData, Error>) -> Void]()
var writeCharacteristicCompletions = [Int: (Result<Void, Error>) -> Void]()
var notifyCharacteristicCompletions = [Int: (Result<Void, Error>) -> Void]()
var readDescriptorCompletions = [Int: (Result<FlutterStandardTypedData, Error>) -> Void]()
var writeDescriptorCompletions = [Int: (Result<Void, Error>) -> Void]()
func setUp(completion: @escaping (Result<MyCentralControllerArgs, Error>) -> Void) {
do {
let unfinishedCompletion = setUpCompletion
if unfinishedCompletion != nil {
throw MyError.illegalState
}
centralManager.delegate = myCentralManagerDelegate
if centralManager.state == .unknown {
setUpCompletion = completion
} else {
let myStateArgs = centralManager.state.toMyArgs()
let myStateNumber = Int64(myStateArgs.rawValue)
let myArgs = MyCentralControllerArgs(myStateNumber: myStateNumber)
completion(.success(myArgs))
}
} catch {
completion(.failure(error))
}
}
func tearDown() throws {
centralManager.delegate = nil
if(centralManager.isScanning) {
centralManager.stopScan()
}
for peripheral in cachedPeripherals.values {
peripheral.delegate = nil
if peripheral.state != .disconnected {
centralManager.cancelPeripheralConnection(peripheral)
}
}
cachedPeripherals.removeAll()
cachedServices.removeAll()
cachedCharacteristics.removeAll()
cachedDescriptors.removeAll()
}
func startDiscovery() throws {
let options = [CBCentralManagerScanOptionAllowDuplicatesKey: true]
centralManager.scanForPeripherals(withServices: nil, options: options)
}
func stopDiscovery() throws {
centralManager.stopScan()
}
func connect(myPeripheralKey: Int64, completion: @escaping (Result<Void, Error>) -> Void) {
do {
let peripheralKey = Int(myPeripheralKey)
let unfinishedCompletion = connectCompletions[peripheralKey]
if unfinishedCompletion != nil {
throw MyError.illegalState
}
guard let peripheral = cachedPeripherals[peripheralKey] else {
throw MyError.illegalArgument
}
centralManager.connect(peripheral)
connectCompletions[peripheralKey] = completion
} catch {
completion(.failure(error))
}
}
func disconnect(myPeripheralKey: Int64, completion: @escaping (Result<Void, Error>) -> Void) {
do {
let peripheralKey = Int(myPeripheralKey)
let unfinishedCompletion = disconnectCompletions[peripheralKey]
if unfinishedCompletion != nil {
throw MyError.illegalState
}
guard let peripheral = cachedPeripherals[peripheralKey] else {
throw MyError.illegalArgument
}
centralManager.cancelPeripheralConnection(peripheral)
disconnectCompletions[peripheralKey] = completion
} catch {
completion(.failure(error))
}
}
func discoverGATT(myPeripheralKey: Int64, completion: @escaping (Result<Void, Error>) -> Void) {
do {
let peripheralKey = Int(myPeripheralKey)
let unfinishedCompletion = discoverGattCompletions[peripheralKey]
if unfinishedCompletion != nil {
throw MyError.illegalState
}
guard let peripheral = cachedPeripherals[peripheralKey] else {
throw MyError.illegalArgument
}
peripheral.discoverServices(nil)
discoverGattCompletions[peripheralKey] = completion
} catch {
completion(.failure(error))
}
}
func getServices(myPeripheralKey: Int64) throws -> [MyGattServiceArgs] {
let peripheralKey = Int(myPeripheralKey)
guard let services = cachedServices[peripheralKey] else {
throw MyError.illegalArgument
}
return services.map { (key, service) in
return service.toMyArgs()
}
}
func getCharacteristics(myServiceKey: Int64) throws -> [MyGattCharacteristicArgs] {
let serviceKey = Int(myServiceKey)
guard let characteristics = cachedCharacteristics[serviceKey] else {
throw MyError.illegalArgument
}
return characteristics.map { (key, characteristic) in
return characteristic.toMyArgs()
}
}
func getDescriptors(myCharacteristicKey: Int64) throws -> [MyGattDescriptorArgs] {
let characteristicKey = Int(myCharacteristicKey)
guard let descriptors = cachedDescriptors[characteristicKey] else {
throw MyError.illegalArgument
}
return descriptors.map { (key, descriptor) in
return descriptor.toMyArgs()
}
}
func readCharacteristic(myPeripheralKey: Int64, myServiceKey: Int64, myCharacteristicKey: Int64, completion: @escaping (Result<FlutterStandardTypedData, Error>) -> Void) {
do {
let peripheralKey = Int(myPeripheralKey)
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)
guard let characteristic = characteristics[characteristicKey] else {
throw MyError.illegalArgument
}
let unfinishedCompletion = readCharacteristicCompletions[characteristicKey]
if unfinishedCompletion != nil {
throw MyError.illegalState
}
peripheral.readValue(for: characteristic)
readCharacteristicCompletions[characteristicKey] = completion
} catch {
completion(.failure(error))
}
}
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 = cachedPeripherals[peripheralKey] else {
throw MyError.illegalArgument
}
let serviceKey = Int(myServiceKey)
guard let characteristics = cachedCharacteristics[serviceKey] else {
throw MyError.illegalArgument
}
let characteristicKey = Int(myCharacteristicKey)
guard let characteristic = characteristics[characteristicKey] else {
throw MyError.illegalArgument
}
let data = value.data
let myTypeRawValue = Int(myTypeNumber)
guard let myTypeArgs = MyGattCharacteristicWriteTypeArgs(rawValue: myTypeRawValue) else {
throw MyError.illegalArgument
}
let type = myTypeArgs.toType()
let unfinishedCompletion = writeCharacteristicCompletions[characteristicKey]
if unfinishedCompletion != nil {
throw MyError.illegalState
}
peripheral.writeValue(data, for: characteristic, type: type)
writeCharacteristicCompletions[characteristicKey] = completion
} catch {
completion(.failure(error))
}
}
func notifyCharacteristic(myPeripheralKey: Int64, myServiceKey: Int64, myCharacteristicKey: Int64, state: Bool, completion: @escaping (Result<Void, Error>) -> Void) {
do {
let peripheralKey = Int(myPeripheralKey)
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)
guard let characteristic = characteristics[characteristicKey] else {
throw MyError.illegalArgument
}
let unfinishedCompletion = notifyCharacteristicCompletions[characteristicKey]
if unfinishedCompletion != nil {
throw MyError.illegalState
}
peripheral.setNotifyValue(state, for: characteristic)
notifyCharacteristicCompletions[characteristicKey] = completion
} catch {
completion(.failure(error))
}
}
func readDescriptor(myPeripheralKey: Int64, myCharacteristicKey: Int64, myDescriptorKey: Int64, completion: @escaping (Result<FlutterStandardTypedData, Error>) -> Void) {
do {
let peripheralKey = Int(myPeripheralKey)
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)
guard let descriptor = descriptors[descriptorKey] else {
throw MyError.illegalArgument
}
let unfinishedCompletion = readDescriptorCompletions[descriptorKey]
if unfinishedCompletion != nil {
throw MyError.illegalState
}
peripheral.readValue(for: descriptor)
readDescriptorCompletions[descriptorKey] = completion
} catch {
completion(.failure(error))
}
}
func writeDescriptor(myPeripheralKey: Int64, myCharacteristicKey: Int64, myDescriptorKey: Int64, value: FlutterStandardTypedData, completion: @escaping (Result<Void, Error>) -> Void) {
do {
let peripheralKey = Int(myPeripheralKey)
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)
guard let descriptor = descriptors[descriptorKey] else {
throw MyError.illegalArgument
}
let data = value.data
let unfinishedCompletion = writeDescriptorCompletions[descriptorKey]
if unfinishedCompletion != nil {
throw MyError.illegalState
}
peripheral.writeValue(data, for: descriptor)
writeDescriptorCompletions[descriptorKey] = completion
} catch {
completion(.failure(error))
}
}
func didUpdateState(_ state: CBManagerState) {
let completion = setUpCompletion
if state != .unknown && completion != nil {
let myStateArgs = state.toMyArgs()
let myStateNumber = Int64(myStateArgs.rawValue)
let myArgs = MyCentralControllerArgs(myStateNumber: myStateNumber)
completion!(.success(myArgs))
setUpCompletion = nil
}
let myStateArgs = state.toMyArgs()
let myStateNumber = Int64(myStateArgs.rawValue)
myApi.onStateChanged(myStateNumber: myStateNumber) {}
}
func didDiscover(_ peripheral: CBPeripheral, _ advertisementData: [String : Any], _ rssiNumber: NSNumber) {
let peripheralKey = peripheral.hash
if cachedPeripherals[peripheralKey] == nil {
peripheral.delegate = myPeripheralDelegate
cachedPeripherals[peripheralKey] = peripheral
}
let myPeripheralArgs = peripheral.toMyArgs()
let rssi = rssiNumber.int64Value
let name = advertisementData[CBAdvertisementDataLocalNameKey] as? String
let rawManufacturerSpecificData = advertisementData[CBAdvertisementDataManufacturerDataKey] as? Data
var manufacturerSpecificData = [Int64: FlutterStandardTypedData]()
if rawManufacturerSpecificData != nil {
do {
guard let data = rawManufacturerSpecificData else {
throw MyError.illegalArgument
}
guard data.count >= 2 else {
throw MyError.illegalArgument
}
let key = Int64(data[0]) | (Int64(data[1]) << 8)
let bytes = data.count > 2 ? data[2...data.count-1] : Data()
let value = FlutterStandardTypedData(bytes: bytes)
manufacturerSpecificData[key] = value
} catch {
manufacturerSpecificData = [:]
}
}
let rawServiceUUIDs = advertisementData[CBAdvertisementDataServiceUUIDsKey] as? [CBUUID] ?? []
let serviceUUIDs = rawServiceUUIDs.map { uuid in uuid.uuidString }
let rawServiceData = advertisementData[CBAdvertisementDataServiceDataKey] as? [CBUUID: Data] ?? [:]
let elements = rawServiceData.map { (uuid, data) in
let key = uuid.uuidString
let value = FlutterStandardTypedData(bytes: data)
return (key, value)
}
let serviceData = [String?: FlutterStandardTypedData?](uniqueKeysWithValues: elements)
let myAdvertisementArgs = MyAdvertisementArgs(name: name, manufacturerSpecificData: manufacturerSpecificData, serviceUUIDs: serviceUUIDs, serviceData: serviceData)
myApi.onDiscovered(myPeripheralArgs: myPeripheralArgs, rssi: rssi, myAdvertisementArgs: myAdvertisementArgs) {}
}
func didConnect(_ peripheral: CBPeripheral) {
let peripheralKey = peripheral.hash
let myPeripheralKey = Int64(peripheralKey)
myApi.onPeripheralStateChanged(myPeripheralKey: myPeripheralKey, state: true) {}
guard let completion = connectCompletions.removeValue(forKey: peripheralKey) else {
return
}
completion(.success(()))
}
func didFailToConnect(_ peripheral: CBPeripheral, _ error: Error?) {
let peripheralKey = peripheral.hash
guard let completion = connectCompletions.removeValue(forKey: peripheralKey) else {
return
}
completion(.failure(error ?? MyError.unknown))
}
func didDisconnectPeripheral(_ peripheral: CBPeripheral, _ error: Error?) {
let peripheralKey = peripheral.hash
let myPeripheralKey = Int64(peripheralKey)
let discoverGattCompletion = discoverGattCompletions.removeValue(forKey: peripheralKey)
if discoverGattCompletion != nil {
didDiscoverGATT(peripheral, error ?? MyError.unknown)
}
let services = cachedServices[peripheralKey] ?? [:]
for service in services {
let characteristics = cachedCharacteristics[service.key] ?? [:]
for characteristic in characteristics {
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 = cachedDescriptors[characteristic.key] ?? [:]
for descriptor in descriptors {
let readDescriptorCompletion = readDescriptorCompletions.removeValue(forKey: descriptor.key)
let writeDescriptorCompletion = writeDescriptorCompletions.removeValue(forKey: descriptor.key)
if readDescriptorCompletion != nil {
readDescriptorCompletion!(.failure(MyError.illegalState))
}
if writeDescriptorCompletion != nil {
writeDescriptorCompletion!(.failure(MyError.illegalState))
}
}
}
}
myApi.onPeripheralStateChanged(myPeripheralKey: myPeripheralKey, state: false) {}
guard let completion = disconnectCompletions.removeValue(forKey: peripheralKey) else {
return
}
if error == nil {
completion(.success(()))
} else {
completion(.failure(error!))
}
}
func didDiscoverServices(_ peripheral: CBPeripheral, _ error: Error?) {
let peripheralKey = peripheral.hash
if error == nil {
var services = peripheral.services ?? []
if services.isEmpty {
didDiscoverGATT(peripheral, error)
} else {
let service = services.removeFirst()
unfinishedServices[peripheralKey] = services
peripheral.discoverCharacteristics(nil, for: service)
}
} else {
didDiscoverGATT(peripheral, error)
}
}
func didDiscoverCharacteristics(_ peripheral: CBPeripheral, _ service: CBService, _ error: Error?) {
let peripheralKey = peripheral.hash
if error == nil {
var characteristics = service.characteristics ?? []
if characteristics.isEmpty {
var services = unfinishedServices.removeValue(forKey: peripheralKey) ?? []
if services.isEmpty {
didDiscoverGATT(peripheral, error)
} else {
let service = services.removeFirst()
unfinishedServices[peripheralKey] = services
peripheral.discoverCharacteristics(nil, for: service)
}
} else {
let characteristic = characteristics.removeFirst()
unfinishedCharacteristics[peripheralKey] = characteristics
peripheral.discoverDescriptors(for: characteristic)
}
} else {
didDiscoverGATT(peripheral, error)
}
}
func didDiscoverDescriptors(_ peripheral: CBPeripheral, _ characteristic: CBCharacteristic, _ error: Error?) {
let peripheralKey = peripheral.hash
if error == nil {
var characteristics = unfinishedCharacteristics.removeValue(forKey: peripheralKey) ?? []
if (characteristics.isEmpty) {
var services = unfinishedServices.removeValue(forKey: peripheralKey) ?? []
if services.isEmpty {
didDiscoverGATT(peripheral, error)
} else {
let service = services.removeFirst()
unfinishedServices[peripheralKey] = services
peripheral.discoverCharacteristics(nil, for: service)
}
} else {
let characteristic = characteristics.removeFirst()
unfinishedCharacteristics[peripheralKey] = characteristics
peripheral.discoverDescriptors(for: characteristic)
}
} else {
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!))
}
}
func didUpdateCharacteristicValue(_ characteristic: CBCharacteristic, _ error: Error?) {
let characteristicKey = characteristic.hash
guard let completion = readCharacteristicCompletions.removeValue(forKey: characteristicKey) else {
let myCharacteristicKey = Int64(characteristicKey)
let rawValue = characteristic.value ?? Data()
let value = FlutterStandardTypedData(bytes: rawValue)
myApi.onCharacteristicValueChanged(myCharacteristicKey: myCharacteristicKey, value: value) {}
return
}
if error == nil {
let rawValue = characteristic.value ?? Data()
let value = FlutterStandardTypedData(bytes: rawValue)
completion(.success(value))
} else {
completion(.failure(error!))
}
}
func didWriteCharacteristicValue(_ characteristic: CBCharacteristic, _ error: Error?) {
let characteristicKey = characteristic.hash
guard let completion = writeCharacteristicCompletions.removeValue(forKey: characteristicKey) else {
return
}
if error == nil {
completion(.success(()))
} else {
completion(.failure(error!))
}
}
func didUpdateNotificationState(_ characteristic: CBCharacteristic, _ error: Error?) {
let characteristicKey = characteristic.hash
guard let completion = notifyCharacteristicCompletions.removeValue(forKey: characteristicKey) else {
return
}
if error == nil {
completion(.success(()))
} else {
completion(.failure(error!))
}
}
func didUpdateDescriptorValue(_ descriptor: CBDescriptor, _ error: Error?) {
let descriptorKey = descriptor.hash
guard let completion = readDescriptorCompletions.removeValue(forKey: descriptorKey) else {
return
}
if error == nil {
// TODO: Need to confirm wheather the corresponding descriptor type and value is correct.
let value: FlutterStandardTypedData
let rawValue = descriptor.value
do {
switch descriptor.uuid.uuidString {
case CBUUIDCharacteristicExtendedPropertiesString:
fallthrough
case CBUUIDClientCharacteristicConfigurationString:
fallthrough
case CBUUIDServerCharacteristicConfigurationString:
guard let rawNumber = rawValue as? NSNumber else {
throw MyError.illegalArgument
}
value = FlutterStandardTypedData(bytes: rawNumber.data)
case CBUUIDCharacteristicUserDescriptionString:
fallthrough
case CBUUIDCharacteristicAggregateFormatString:
guard let rawString = rawValue as? String else {
throw MyError.illegalArgument
}
value = FlutterStandardTypedData(bytes: rawString.data)
case CBUUIDCharacteristicFormatString:
guard let rawData = rawValue as? Data else {
throw MyError.illegalArgument
}
value = FlutterStandardTypedData(bytes: rawData)
case CBUUIDL2CAPPSMCharacteristicString:
guard let rawU16 = rawValue as? UInt16 else {
throw MyError.illegalArgument
}
value = FlutterStandardTypedData(bytes: rawU16.data)
default:
throw MyError.illegalArgument
}
} catch {
value = FlutterStandardTypedData()
}
completion(.success((value)))
} else {
completion(.failure(error!))
}
}
func didWriteDescriptorValue(_ descriptor: CBDescriptor, _ error: Error?) {
let descriptorKey = descriptor.hash
guard let completion = writeDescriptorCompletions.removeValue(forKey: descriptorKey) else {
return
}
if error == nil {
completion(.success(()))
} else {
completion(.failure(error!))
}
}
}
extension CBManagerState {
func toMyArgs() -> MyCentralStateArgs {
switch self {
case .unauthorized:
return .unauthorized
case .poweredOff:
return .poweredOff
case .poweredOn:
return .poweredOn
default:
return .unsupported
}
}
}
extension CBPeripheral {
func toMyArgs() -> MyPeripheralArgs {
let key = Int64(hash)
let uuid = identifier.uuidString
return MyPeripheralArgs(key: key, uuid: uuid)
}
}
extension CBService {
func toMyArgs() -> MyGattServiceArgs {
let key = Int64(hash)
let uuid = uuid.uuidString
return MyGattServiceArgs(key: key, uuid: uuid)
}
}
extension CBCharacteristic {
func toMyArgs() -> MyGattCharacteristicArgs {
let key = Int64(hash)
let uuid = uuid.uuidString
let myPropertyArgses = properties.toMyArgses()
let myPropertyNumbers = myPropertyArgses.map { myPropertyArgs in Int64(myPropertyArgs.rawValue) }
return MyGattCharacteristicArgs(key: key, uuid: uuid, myPropertyNumbers: myPropertyNumbers)
}
}
extension CBDescriptor {
func toMyArgs() -> MyGattDescriptorArgs {
let key = Int64(hash)
let uuid = uuid.uuidString
return MyGattDescriptorArgs(key: key, uuid: uuid)
}
}
extension CBCharacteristicProperties {
func toMyArgses() -> [MyGattCharacteristicPropertyArgs] {
var myPropertyArgs = [MyGattCharacteristicPropertyArgs]()
if contains(.read) {
myPropertyArgs.append(.read)
}
if contains(.write) {
myPropertyArgs.append(.write)
}
if contains(.writeWithoutResponse) {
myPropertyArgs.append(.writeWithoutResponse)
}
if contains(.notify) {
myPropertyArgs.append(.notify)
}
if contains(.indicate) {
myPropertyArgs.append(.indicate)
}
return myPropertyArgs
}
}
extension MyGattCharacteristicWriteTypeArgs {
func toType() -> CBCharacteristicWriteType {
switch self {
case .withResponse:
return .withResponse
case .withoutResponse:
return .withoutResponse
}
}
}
extension NSNumber {
var data: Data {
var source = self
return Data(bytes: &source, count: MemoryLayout<NSNumber>.size)
}
}
extension String {
var data: Data {
return data(using: String.Encoding.utf8)!
}
}
extension UInt16 {
var data: Data {
var source = self
return Data(bytes: &source, count: MemoryLayout<UInt16>.size)
}
}

View File

@ -0,0 +1,38 @@
//
// MyCentralManagerDelegate.swift
// bluetooth_low_energy_ios
//
// Created by on 2023/8/13.
//
import Foundation
import CoreBluetooth
class MyCentralManagerDelegate: NSObject, CBCentralManagerDelegate {
private let myCentralController: MyCentralController
init(_ myCentralController: MyCentralController) {
self.myCentralController = myCentralController
}
func centralManagerDidUpdateState(_ central: CBCentralManager) {
let state = central.state
myCentralController.didUpdateState(state)
}
func centralManager(_ central: CBCentralManager, didDiscover peripheral: CBPeripheral, advertisementData: [String : Any], rssi RSSI: NSNumber) {
myCentralController.didDiscover(peripheral, advertisementData, RSSI)
}
func centralManager(_ central: CBCentralManager, didConnect peripheral: CBPeripheral) {
myCentralController.didConnect(peripheral)
}
func centralManager(_ central: CBCentralManager, didFailToConnect peripheral: CBPeripheral, error: Error?) {
myCentralController.didFailToConnect(peripheral, error)
}
func centralManager(_ central: CBCentralManager, didDisconnectPeripheral peripheral: CBPeripheral, error: Error?) {
myCentralController.didDisconnectPeripheral(peripheral, error)
}
}

View File

@ -0,0 +1,14 @@
//
// MyError.swift
// bluetooth_low_energy_ios
//
// Created by on 2023/8/13.
//
import Foundation
enum MyError: Error {
case illegalArgument
case illegalState
case unknown
}

View File

@ -0,0 +1,49 @@
//
// MyPeripheralDelegate.swift
// bluetooth_low_energy_ios
//
// Created by on 2023/8/13.
//
import Foundation
import CoreBluetooth
class MyPeripheralDelegate: NSObject, CBPeripheralDelegate {
private let myCentralController: MyCentralController
init(_ myCentralController: MyCentralController) {
self.myCentralController = myCentralController
}
func peripheral(_ peripheral: CBPeripheral, didDiscoverServices error: Error?) {
myCentralController.didDiscoverServices(peripheral, error)
}
func peripheral(_ peripheral: CBPeripheral, didDiscoverCharacteristicsFor service: CBService, error: Error?) {
myCentralController.didDiscoverCharacteristics(peripheral, service, error)
}
func peripheral(_ peripheral: CBPeripheral, didDiscoverDescriptorsFor characteristic: CBCharacteristic, error: Error?) {
myCentralController.didDiscoverDescriptors(peripheral, characteristic, error)
}
func peripheral(_ peripheral: CBPeripheral, didUpdateValueFor characteristic: CBCharacteristic, error: Error?) {
myCentralController.didUpdateCharacteristicValue(characteristic, error)
}
func peripheral(_ peripheral: CBPeripheral, didWriteValueFor characteristic: CBCharacteristic, error: Error?) {
myCentralController.didWriteCharacteristicValue(characteristic, error)
}
func peripheral(_ peripheral: CBPeripheral, didUpdateNotificationStateFor characteristic: CBCharacteristic, error: Error?) {
myCentralController.didUpdateNotificationState(characteristic, error)
}
func peripheral(_ peripheral: CBPeripheral, didUpdateValueFor descriptor: CBDescriptor, error: Error?) {
myCentralController.didUpdateDescriptorValue(descriptor, error)
}
func peripheral(_ peripheral: CBPeripheral, didWriteValueFor descriptor: CBDescriptor, error: Error?) {
myCentralController.didWriteDescriptorValue(descriptor, error)
}
}

View File

@ -0,0 +1,27 @@
#
# To learn more about a Podspec see http://guides.cocoapods.org/syntax/podspec.html.
# Run `pod lib lint bluetooth_low_energy_darwin.podspec` to validate before publishing.
#
Pod::Spec.new do |s|
s.name = 'bluetooth_low_energy_darwin'
s.version = '2.0.2'
s.summary = 'iOS and macOS implementation of the bluetooth_low_energy plugin.'
s.description = <<-DESC
iOS and macOS implementation of the bluetooth_low_energy plugin.
DESC
s.homepage = 'https://github.com/yanshouwang/bluetooth_low_energy'
s.license = { :file => '../LICENSE' }
s.author = { 'yanshouwang' => 'yanshouwang@outlook.com' }
s.source = { :path => '.' }
s.source_files = 'Classes/**/*'
s.ios.dependency 'Flutter'
s.ios.deployment_target = '11.0'
s.osx.dependency 'FlutterMacOS'
s.osx.deployment_target = '10.11'
s.pod_target_xcconfig = { 'DEFINES_MODULE' => 'YES' }
s.swift_version = '5.0'
end

View File

@ -0,0 +1,9 @@
import 'package:bluetooth_low_energy_platform_interface/bluetooth_low_energy_platform_interface.dart';
import 'src/my_central_controller.dart';
abstract class BluetoothLowEnergyDarwin {
static void registerWith() {
CentralController.instance = MyCentralController();
}
}

View File

@ -0,0 +1,736 @@
// Autogenerated from Pigeon (v10.1.6), do not edit directly.
// See also: https://pub.dev/packages/pigeon
// ignore_for_file: public_member_api_docs, non_constant_identifier_names, avoid_as, unused_import, unnecessary_parenthesis, prefer_null_aware_operators, omit_local_variable_types, unused_shown_name, unnecessary_import
import 'dart:async';
import 'dart:typed_data' show Float64List, Int32List, Int64List, Uint8List;
import 'package:flutter/foundation.dart' show ReadBuffer, WriteBuffer;
import 'package:flutter/services.dart';
enum MyCentralStateArgs {
unknown,
unsupported,
unauthorized,
poweredOff,
poweredOn,
}
enum MyGattCharacteristicPropertyArgs {
read,
write,
writeWithoutResponse,
notify,
indicate,
}
enum MyGattCharacteristicWriteTypeArgs {
withResponse,
withoutResponse,
}
class MyCentralControllerArgs {
MyCentralControllerArgs({
required this.myStateNumber,
});
int myStateNumber;
Object encode() {
return <Object?>[
myStateNumber,
];
}
static MyCentralControllerArgs decode(Object result) {
result as List<Object?>;
return MyCentralControllerArgs(
myStateNumber: result[0]! as int,
);
}
}
class MyPeripheralArgs {
MyPeripheralArgs({
required this.key,
required this.uuid,
});
int key;
String uuid;
Object encode() {
return <Object?>[
key,
uuid,
];
}
static MyPeripheralArgs decode(Object result) {
result as List<Object?>;
return MyPeripheralArgs(
key: result[0]! as int,
uuid: result[1]! as String,
);
}
}
class MyAdvertisementArgs {
MyAdvertisementArgs({
this.name,
required this.manufacturerSpecificData,
required this.serviceUUIDs,
required this.serviceData,
});
String? name;
Map<int?, Uint8List?> manufacturerSpecificData;
List<String?> serviceUUIDs;
Map<String?, Uint8List?> serviceData;
Object encode() {
return <Object?>[
name,
manufacturerSpecificData,
serviceUUIDs,
serviceData,
];
}
static MyAdvertisementArgs decode(Object result) {
result as List<Object?>;
return MyAdvertisementArgs(
name: result[0] as String?,
manufacturerSpecificData: (result[1] as Map<Object?, Object?>?)!.cast<int?, Uint8List?>(),
serviceUUIDs: (result[2] as List<Object?>?)!.cast<String?>(),
serviceData: (result[3] as Map<Object?, Object?>?)!.cast<String?, Uint8List?>(),
);
}
}
class MyGattServiceArgs {
MyGattServiceArgs({
required this.key,
required this.uuid,
});
int key;
String uuid;
Object encode() {
return <Object?>[
key,
uuid,
];
}
static MyGattServiceArgs decode(Object result) {
result as List<Object?>;
return MyGattServiceArgs(
key: result[0]! as int,
uuid: result[1]! as String,
);
}
}
class MyGattCharacteristicArgs {
MyGattCharacteristicArgs({
required this.key,
required this.uuid,
required this.myPropertyNumbers,
});
int key;
String uuid;
List<int?> myPropertyNumbers;
Object encode() {
return <Object?>[
key,
uuid,
myPropertyNumbers,
];
}
static MyGattCharacteristicArgs decode(Object result) {
result as List<Object?>;
return MyGattCharacteristicArgs(
key: result[0]! as int,
uuid: result[1]! as String,
myPropertyNumbers: (result[2] as List<Object?>?)!.cast<int?>(),
);
}
}
class MyGattDescriptorArgs {
MyGattDescriptorArgs({
required this.key,
required this.uuid,
});
int key;
String uuid;
Object encode() {
return <Object?>[
key,
uuid,
];
}
static MyGattDescriptorArgs decode(Object result) {
result as List<Object?>;
return MyGattDescriptorArgs(
key: result[0]! as int,
uuid: result[1]! as String,
);
}
}
class _MyCentralControllerHostApiCodec extends StandardMessageCodec {
const _MyCentralControllerHostApiCodec();
@override
void writeValue(WriteBuffer buffer, Object? value) {
if (value is MyCentralControllerArgs) {
buffer.putUint8(128);
writeValue(buffer, value.encode());
} else if (value is MyGattCharacteristicArgs) {
buffer.putUint8(129);
writeValue(buffer, value.encode());
} else if (value is MyGattDescriptorArgs) {
buffer.putUint8(130);
writeValue(buffer, value.encode());
} else if (value is MyGattServiceArgs) {
buffer.putUint8(131);
writeValue(buffer, value.encode());
} else {
super.writeValue(buffer, value);
}
}
@override
Object? readValueOfType(int type, ReadBuffer buffer) {
switch (type) {
case 128:
return MyCentralControllerArgs.decode(readValue(buffer)!);
case 129:
return MyGattCharacteristicArgs.decode(readValue(buffer)!);
case 130:
return MyGattDescriptorArgs.decode(readValue(buffer)!);
case 131:
return MyGattServiceArgs.decode(readValue(buffer)!);
default:
return super.readValueOfType(type, buffer);
}
}
}
class MyCentralControllerHostApi {
/// Constructor for [MyCentralControllerHostApi]. The [binaryMessenger] named argument is
/// available for dependency injection. If it is left null, the default
/// BinaryMessenger will be used which routes to the host platform.
MyCentralControllerHostApi({BinaryMessenger? binaryMessenger})
: _binaryMessenger = binaryMessenger;
final BinaryMessenger? _binaryMessenger;
static const MessageCodec<Object?> codec = _MyCentralControllerHostApiCodec();
Future<MyCentralControllerArgs> setUp() async {
final BasicMessageChannel<Object?> channel = BasicMessageChannel<Object?>(
'dev.flutter.pigeon.bluetooth_low_energy_darwin.MyCentralControllerHostApi.setUp', codec,
binaryMessenger: _binaryMessenger);
final List<Object?>? replyList =
await channel.send(null) as List<Object?>?;
if (replyList == null) {
throw PlatformException(
code: 'channel-error',
message: 'Unable to establish connection on channel.',
);
} else if (replyList.length > 1) {
throw PlatformException(
code: replyList[0]! as String,
message: replyList[1] as String?,
details: replyList[2],
);
} else if (replyList[0] == null) {
throw PlatformException(
code: 'null-error',
message: 'Host platform returned null value for non-null return value.',
);
} else {
return (replyList[0] as MyCentralControllerArgs?)!;
}
}
Future<void> tearDown() async {
final BasicMessageChannel<Object?> channel = BasicMessageChannel<Object?>(
'dev.flutter.pigeon.bluetooth_low_energy_darwin.MyCentralControllerHostApi.tearDown', codec,
binaryMessenger: _binaryMessenger);
final List<Object?>? replyList =
await channel.send(null) as List<Object?>?;
if (replyList == null) {
throw PlatformException(
code: 'channel-error',
message: 'Unable to establish connection on channel.',
);
} else if (replyList.length > 1) {
throw PlatformException(
code: replyList[0]! as String,
message: replyList[1] as String?,
details: replyList[2],
);
} else {
return;
}
}
Future<void> startDiscovery() async {
final BasicMessageChannel<Object?> channel = BasicMessageChannel<Object?>(
'dev.flutter.pigeon.bluetooth_low_energy_darwin.MyCentralControllerHostApi.startDiscovery', codec,
binaryMessenger: _binaryMessenger);
final List<Object?>? replyList =
await channel.send(null) as List<Object?>?;
if (replyList == null) {
throw PlatformException(
code: 'channel-error',
message: 'Unable to establish connection on channel.',
);
} else if (replyList.length > 1) {
throw PlatformException(
code: replyList[0]! as String,
message: replyList[1] as String?,
details: replyList[2],
);
} else {
return;
}
}
Future<void> stopDiscovery() async {
final BasicMessageChannel<Object?> channel = BasicMessageChannel<Object?>(
'dev.flutter.pigeon.bluetooth_low_energy_darwin.MyCentralControllerHostApi.stopDiscovery', codec,
binaryMessenger: _binaryMessenger);
final List<Object?>? replyList =
await channel.send(null) as List<Object?>?;
if (replyList == null) {
throw PlatformException(
code: 'channel-error',
message: 'Unable to establish connection on channel.',
);
} else if (replyList.length > 1) {
throw PlatformException(
code: replyList[0]! as String,
message: replyList[1] as String?,
details: replyList[2],
);
} else {
return;
}
}
Future<void> connect(int arg_myPeripheralKey) async {
final BasicMessageChannel<Object?> channel = BasicMessageChannel<Object?>(
'dev.flutter.pigeon.bluetooth_low_energy_darwin.MyCentralControllerHostApi.connect', codec,
binaryMessenger: _binaryMessenger);
final List<Object?>? replyList =
await channel.send(<Object?>[arg_myPeripheralKey]) as List<Object?>?;
if (replyList == null) {
throw PlatformException(
code: 'channel-error',
message: 'Unable to establish connection on channel.',
);
} else if (replyList.length > 1) {
throw PlatformException(
code: replyList[0]! as String,
message: replyList[1] as String?,
details: replyList[2],
);
} else {
return;
}
}
Future<void> disconnect(int arg_myPeripheralKey) async {
final BasicMessageChannel<Object?> channel = BasicMessageChannel<Object?>(
'dev.flutter.pigeon.bluetooth_low_energy_darwin.MyCentralControllerHostApi.disconnect', codec,
binaryMessenger: _binaryMessenger);
final List<Object?>? replyList =
await channel.send(<Object?>[arg_myPeripheralKey]) as List<Object?>?;
if (replyList == null) {
throw PlatformException(
code: 'channel-error',
message: 'Unable to establish connection on channel.',
);
} else if (replyList.length > 1) {
throw PlatformException(
code: replyList[0]! as String,
message: replyList[1] as String?,
details: replyList[2],
);
} else {
return;
}
}
Future<void> discoverGATT(int arg_myPeripheralKey) async {
final BasicMessageChannel<Object?> channel = BasicMessageChannel<Object?>(
'dev.flutter.pigeon.bluetooth_low_energy_darwin.MyCentralControllerHostApi.discoverGATT', codec,
binaryMessenger: _binaryMessenger);
final List<Object?>? replyList =
await channel.send(<Object?>[arg_myPeripheralKey]) as List<Object?>?;
if (replyList == null) {
throw PlatformException(
code: 'channel-error',
message: 'Unable to establish connection on channel.',
);
} else if (replyList.length > 1) {
throw PlatformException(
code: replyList[0]! as String,
message: replyList[1] as String?,
details: replyList[2],
);
} else {
return;
}
}
Future<List<MyGattServiceArgs?>> getServices(int arg_myPeripheralKey) async {
final BasicMessageChannel<Object?> channel = BasicMessageChannel<Object?>(
'dev.flutter.pigeon.bluetooth_low_energy_darwin.MyCentralControllerHostApi.getServices', codec,
binaryMessenger: _binaryMessenger);
final List<Object?>? replyList =
await channel.send(<Object?>[arg_myPeripheralKey]) as List<Object?>?;
if (replyList == null) {
throw PlatformException(
code: 'channel-error',
message: 'Unable to establish connection on channel.',
);
} else if (replyList.length > 1) {
throw PlatformException(
code: replyList[0]! as String,
message: replyList[1] as String?,
details: replyList[2],
);
} else if (replyList[0] == null) {
throw PlatformException(
code: 'null-error',
message: 'Host platform returned null value for non-null return value.',
);
} else {
return (replyList[0] as List<Object?>?)!.cast<MyGattServiceArgs?>();
}
}
Future<List<MyGattCharacteristicArgs?>> getCharacteristics(int arg_myServiceKey) async {
final BasicMessageChannel<Object?> channel = BasicMessageChannel<Object?>(
'dev.flutter.pigeon.bluetooth_low_energy_darwin.MyCentralControllerHostApi.getCharacteristics', codec,
binaryMessenger: _binaryMessenger);
final List<Object?>? replyList =
await channel.send(<Object?>[arg_myServiceKey]) as List<Object?>?;
if (replyList == null) {
throw PlatformException(
code: 'channel-error',
message: 'Unable to establish connection on channel.',
);
} else if (replyList.length > 1) {
throw PlatformException(
code: replyList[0]! as String,
message: replyList[1] as String?,
details: replyList[2],
);
} else if (replyList[0] == null) {
throw PlatformException(
code: 'null-error',
message: 'Host platform returned null value for non-null return value.',
);
} else {
return (replyList[0] as List<Object?>?)!.cast<MyGattCharacteristicArgs?>();
}
}
Future<List<MyGattDescriptorArgs?>> getDescriptors(int arg_myCharacteristicKey) async {
final BasicMessageChannel<Object?> channel = BasicMessageChannel<Object?>(
'dev.flutter.pigeon.bluetooth_low_energy_darwin.MyCentralControllerHostApi.getDescriptors', codec,
binaryMessenger: _binaryMessenger);
final List<Object?>? replyList =
await channel.send(<Object?>[arg_myCharacteristicKey]) as List<Object?>?;
if (replyList == null) {
throw PlatformException(
code: 'channel-error',
message: 'Unable to establish connection on channel.',
);
} else if (replyList.length > 1) {
throw PlatformException(
code: replyList[0]! as String,
message: replyList[1] as String?,
details: replyList[2],
);
} else if (replyList[0] == null) {
throw PlatformException(
code: 'null-error',
message: 'Host platform returned null value for non-null return value.',
);
} else {
return (replyList[0] as List<Object?>?)!.cast<MyGattDescriptorArgs?>();
}
}
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_darwin.MyCentralControllerHostApi.readCharacteristic', codec,
binaryMessenger: _binaryMessenger);
final List<Object?>? replyList =
await channel.send(<Object?>[arg_myPeripheralKey, arg_myServiceKey, arg_myCharacteristicKey]) as List<Object?>?;
if (replyList == null) {
throw PlatformException(
code: 'channel-error',
message: 'Unable to establish connection on channel.',
);
} else if (replyList.length > 1) {
throw PlatformException(
code: replyList[0]! as String,
message: replyList[1] as String?,
details: replyList[2],
);
} else if (replyList[0] == null) {
throw PlatformException(
code: 'null-error',
message: 'Host platform returned null value for non-null return value.',
);
} else {
return (replyList[0] as Uint8List?)!;
}
}
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_darwin.MyCentralControllerHostApi.writeCharacteristic', codec,
binaryMessenger: _binaryMessenger);
final List<Object?>? replyList =
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',
message: 'Unable to establish connection on channel.',
);
} else if (replyList.length > 1) {
throw PlatformException(
code: replyList[0]! as String,
message: replyList[1] as String?,
details: replyList[2],
);
} else {
return;
}
}
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_darwin.MyCentralControllerHostApi.notifyCharacteristic', codec,
binaryMessenger: _binaryMessenger);
final List<Object?>? replyList =
await channel.send(<Object?>[arg_myPeripheralKey, arg_myServiceKey, arg_myCharacteristicKey, arg_state]) as List<Object?>?;
if (replyList == null) {
throw PlatformException(
code: 'channel-error',
message: 'Unable to establish connection on channel.',
);
} else if (replyList.length > 1) {
throw PlatformException(
code: replyList[0]! as String,
message: replyList[1] as String?,
details: replyList[2],
);
} else {
return;
}
}
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_darwin.MyCentralControllerHostApi.readDescriptor', codec,
binaryMessenger: _binaryMessenger);
final List<Object?>? replyList =
await channel.send(<Object?>[arg_myPeripheralKey, arg_myCharacteristicKey, arg_myDescriptorKey]) as List<Object?>?;
if (replyList == null) {
throw PlatformException(
code: 'channel-error',
message: 'Unable to establish connection on channel.',
);
} else if (replyList.length > 1) {
throw PlatformException(
code: replyList[0]! as String,
message: replyList[1] as String?,
details: replyList[2],
);
} else if (replyList[0] == null) {
throw PlatformException(
code: 'null-error',
message: 'Host platform returned null value for non-null return value.',
);
} else {
return (replyList[0] as Uint8List?)!;
}
}
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_darwin.MyCentralControllerHostApi.writeDescriptor', codec,
binaryMessenger: _binaryMessenger);
final List<Object?>? replyList =
await channel.send(<Object?>[arg_myPeripheralKey, arg_myCharacteristicKey, arg_myDescriptorKey, arg_value]) as List<Object?>?;
if (replyList == null) {
throw PlatformException(
code: 'channel-error',
message: 'Unable to establish connection on channel.',
);
} else if (replyList.length > 1) {
throw PlatformException(
code: replyList[0]! as String,
message: replyList[1] as String?,
details: replyList[2],
);
} else {
return;
}
}
}
class _MyCentralControllerFlutterApiCodec extends StandardMessageCodec {
const _MyCentralControllerFlutterApiCodec();
@override
void writeValue(WriteBuffer buffer, Object? value) {
if (value is MyAdvertisementArgs) {
buffer.putUint8(128);
writeValue(buffer, value.encode());
} else if (value is MyPeripheralArgs) {
buffer.putUint8(129);
writeValue(buffer, value.encode());
} else {
super.writeValue(buffer, value);
}
}
@override
Object? readValueOfType(int type, ReadBuffer buffer) {
switch (type) {
case 128:
return MyAdvertisementArgs.decode(readValue(buffer)!);
case 129:
return MyPeripheralArgs.decode(readValue(buffer)!);
default:
return super.readValueOfType(type, buffer);
}
}
}
abstract class MyCentralControllerFlutterApi {
static const MessageCodec<Object?> codec = _MyCentralControllerFlutterApiCodec();
void onStateChanged(int myStateNumber);
void onDiscovered(MyPeripheralArgs myPeripheralArgs, int rssi, MyAdvertisementArgs myAdvertisementArgs);
void onPeripheralStateChanged(int myPeripheralKey, bool state);
void onCharacteristicValueChanged(int myCharacteristicKey, Uint8List value);
static void setup(MyCentralControllerFlutterApi? api, {BinaryMessenger? binaryMessenger}) {
{
final BasicMessageChannel<Object?> channel = BasicMessageChannel<Object?>(
'dev.flutter.pigeon.bluetooth_low_energy_darwin.MyCentralControllerFlutterApi.onStateChanged', codec,
binaryMessenger: binaryMessenger);
if (api == null) {
channel.setMessageHandler(null);
} else {
channel.setMessageHandler((Object? message) async {
assert(message != null,
'Argument for dev.flutter.pigeon.bluetooth_low_energy_darwin.MyCentralControllerFlutterApi.onStateChanged was null.');
final List<Object?> args = (message as List<Object?>?)!;
final int? arg_myStateNumber = (args[0] as int?);
assert(arg_myStateNumber != null,
'Argument for dev.flutter.pigeon.bluetooth_low_energy_darwin.MyCentralControllerFlutterApi.onStateChanged was null, expected non-null int.');
api.onStateChanged(arg_myStateNumber!);
return;
});
}
}
{
final BasicMessageChannel<Object?> channel = BasicMessageChannel<Object?>(
'dev.flutter.pigeon.bluetooth_low_energy_darwin.MyCentralControllerFlutterApi.onDiscovered', codec,
binaryMessenger: binaryMessenger);
if (api == null) {
channel.setMessageHandler(null);
} else {
channel.setMessageHandler((Object? message) async {
assert(message != null,
'Argument for dev.flutter.pigeon.bluetooth_low_energy_darwin.MyCentralControllerFlutterApi.onDiscovered was null.');
final List<Object?> args = (message as List<Object?>?)!;
final MyPeripheralArgs? arg_myPeripheralArgs = (args[0] as MyPeripheralArgs?);
assert(arg_myPeripheralArgs != null,
'Argument for dev.flutter.pigeon.bluetooth_low_energy_darwin.MyCentralControllerFlutterApi.onDiscovered was null, expected non-null MyPeripheralArgs.');
final int? arg_rssi = (args[1] as int?);
assert(arg_rssi != null,
'Argument for dev.flutter.pigeon.bluetooth_low_energy_darwin.MyCentralControllerFlutterApi.onDiscovered was null, expected non-null int.');
final MyAdvertisementArgs? arg_myAdvertisementArgs = (args[2] as MyAdvertisementArgs?);
assert(arg_myAdvertisementArgs != null,
'Argument for dev.flutter.pigeon.bluetooth_low_energy_darwin.MyCentralControllerFlutterApi.onDiscovered was null, expected non-null MyAdvertisementArgs.');
api.onDiscovered(arg_myPeripheralArgs!, arg_rssi!, arg_myAdvertisementArgs!);
return;
});
}
}
{
final BasicMessageChannel<Object?> channel = BasicMessageChannel<Object?>(
'dev.flutter.pigeon.bluetooth_low_energy_darwin.MyCentralControllerFlutterApi.onPeripheralStateChanged', codec,
binaryMessenger: binaryMessenger);
if (api == null) {
channel.setMessageHandler(null);
} else {
channel.setMessageHandler((Object? message) async {
assert(message != null,
'Argument for dev.flutter.pigeon.bluetooth_low_energy_darwin.MyCentralControllerFlutterApi.onPeripheralStateChanged was null.');
final List<Object?> args = (message as List<Object?>?)!;
final int? arg_myPeripheralKey = (args[0] as int?);
assert(arg_myPeripheralKey != null,
'Argument for dev.flutter.pigeon.bluetooth_low_energy_darwin.MyCentralControllerFlutterApi.onPeripheralStateChanged was null, expected non-null int.');
final bool? arg_state = (args[1] as bool?);
assert(arg_state != null,
'Argument for dev.flutter.pigeon.bluetooth_low_energy_darwin.MyCentralControllerFlutterApi.onPeripheralStateChanged was null, expected non-null bool.');
api.onPeripheralStateChanged(arg_myPeripheralKey!, arg_state!);
return;
});
}
}
{
final BasicMessageChannel<Object?> channel = BasicMessageChannel<Object?>(
'dev.flutter.pigeon.bluetooth_low_energy_darwin.MyCentralControllerFlutterApi.onCharacteristicValueChanged', codec,
binaryMessenger: binaryMessenger);
if (api == null) {
channel.setMessageHandler(null);
} else {
channel.setMessageHandler((Object? message) async {
assert(message != null,
'Argument for dev.flutter.pigeon.bluetooth_low_energy_darwin.MyCentralControllerFlutterApi.onCharacteristicValueChanged was null.');
final List<Object?> args = (message as List<Object?>?)!;
final int? arg_myCharacteristicKey = (args[0] as int?);
assert(arg_myCharacteristicKey != null,
'Argument for dev.flutter.pigeon.bluetooth_low_energy_darwin.MyCentralControllerFlutterApi.onCharacteristicValueChanged was null, expected non-null int.');
final Uint8List? arg_value = (args[1] as Uint8List?);
assert(arg_value != null,
'Argument for dev.flutter.pigeon.bluetooth_low_energy_darwin.MyCentralControllerFlutterApi.onCharacteristicValueChanged was null, expected non-null Uint8List.');
api.onCharacteristicValueChanged(arg_myCharacteristicKey!, arg_value!);
return;
});
}
}
}
}

View File

@ -0,0 +1,354 @@
import 'dart:async';
import 'dart:typed_data';
import 'package:bluetooth_low_energy_platform_interface/bluetooth_low_energy_platform_interface.dart';
import 'my_api.g.dart';
import 'my_gatt_characteristic.dart';
import 'my_gatt_descriptor.dart';
import 'my_gatt_service.dart';
import 'my_peripheral.dart';
class MyCentralController extends CentralController
implements MyCentralControllerFlutterApi {
MyCentralController()
: _myApi = MyCentralControllerHostApi(),
_stateChangedController = StreamController.broadcast(),
_discoveredController = StreamController.broadcast(),
_peripheralStateChangedController = StreamController.broadcast(),
_characteristicValueChangedController = StreamController.broadcast(),
_myPeripherals = {},
_myServices = {},
_myCharacteristics = {},
_myDescriptors = {},
_state = CentralState.unknown;
final MyCentralControllerHostApi _myApi;
final StreamController<CentralStateChangedEventArgs> _stateChangedController;
final StreamController<CentralDiscoveredEventArgs> _discoveredController;
final StreamController<PeripheralStateChangedEventArgs>
_peripheralStateChangedController;
final StreamController<GattCharacteristicValueChangedEventArgs>
_characteristicValueChangedController;
final Map<int, MyPeripheral> _myPeripherals;
final Map<int, MyGattService> _myServices;
final Map<int, MyGattCharacteristic> _myCharacteristics;
final Map<int, MyGattDescriptor> _myDescriptors;
CentralState _state;
@override
CentralState get state => _state;
@override
Stream<CentralStateChangedEventArgs> get stateChanged =>
_stateChangedController.stream;
@override
Stream<CentralDiscoveredEventArgs> get discovered =>
_discoveredController.stream;
@override
Stream<PeripheralStateChangedEventArgs> get peripheralStateChanged =>
_peripheralStateChangedController.stream;
@override
Stream<GattCharacteristicValueChangedEventArgs>
get characteristicValueChanged =>
_characteristicValueChangedController.stream;
Future<void> _throwWithState(CentralState state) async {
if (this.state == state) {
throw BluetoothLowEnergyError('$state is unexpected.');
}
}
Future<void> _throwWithoutState(CentralState state) async {
if (this.state != state) {
throw BluetoothLowEnergyError(
'$state is expected, but current state is ${this.state}.',
);
}
}
@override
Future<void> setUp() async {
await _throwWithoutState(CentralState.unknown);
final args = await _myApi.setUp();
final myStateArgs = MyCentralStateArgs.values[args.myStateNumber];
_state = myStateArgs.toState();
MyCentralControllerFlutterApi.setup(this);
}
@override
Future<void> tearDown() async {
await _throwWithState(CentralState.unknown);
await _myApi.tearDown();
MyCentralControllerFlutterApi.setup(null);
_myPeripherals.clear();
_myServices.clear();
_myCharacteristics.clear();
_myDescriptors.clear();
_state = CentralState.unknown;
}
@override
Future<void> startDiscovery() async {
await _throwWithoutState(CentralState.poweredOn);
await _myApi.startDiscovery();
}
@override
Future<void> stopDiscovery() async {
await _throwWithoutState(CentralState.poweredOn);
await _myApi.stopDiscovery();
}
@override
Future<void> connect(Peripheral peripheral) async {
await _throwWithoutState(CentralState.poweredOn);
final myPeripheral = peripheral as MyPeripheral;
await _myApi.connect(myPeripheral.hashCode);
}
@override
Future<void> disconnect(Peripheral peripheral) async {
await _throwWithoutState(CentralState.poweredOn);
final myPeripheral = peripheral as MyPeripheral;
await _myApi.disconnect(myPeripheral.hashCode);
}
@override
Future<void> discoverGATT(Peripheral peripheral) async {
await _throwWithoutState(CentralState.poweredOn);
final myPeripheral = peripheral as MyPeripheral;
await _myApi.discoverGATT(myPeripheral.hashCode);
}
@override
Future<List<GattService>> getServices(Peripheral peripheral) async {
await _throwWithoutState(CentralState.poweredOn);
final myPeripheral = peripheral as MyPeripheral;
final myServiceArgses = await _myApi.getServices(myPeripheral.hashCode);
return myServiceArgses.cast<MyGattServiceArgs>().map(
(myServiceArgs) {
final myService = MyGattService.fromMyArgs(
myPeripheral,
myServiceArgs,
);
_myServices[myService.hashCode] = myService;
return myService;
},
).toList();
}
@override
Future<List<GattCharacteristic>> getCharacteristics(
GattService service,
) async {
await _throwWithoutState(CentralState.poweredOn);
final myService = service as MyGattService;
final myCharactersiticArgses = await _myApi.getCharacteristics(
myService.hashCode,
);
return myCharactersiticArgses.cast<MyGattCharacteristicArgs>().map(
(myCharacteristicArgs) {
final myCharacteristic = MyGattCharacteristic.fromMyArgs(
myService,
myCharacteristicArgs,
);
_myCharacteristics[myCharacteristic.hashCode] = myCharacteristic;
return myCharacteristic;
},
).toList();
}
@override
Future<List<GattDescriptor>> getDescriptors(
GattCharacteristic characteristic,
) async {
await _throwWithoutState(CentralState.poweredOn);
final myCharacteristic = characteristic as MyGattCharacteristic;
final myDescriptorArgses = await _myApi.getDescriptors(
myCharacteristic.hashCode,
);
return myDescriptorArgses.cast<MyGattDescriptorArgs>().map(
(myDescriptorArgs) {
final myDescriptor = MyGattDescriptor.fromMyArgs(
myCharacteristic,
myDescriptorArgs,
);
_myDescriptors[myDescriptor.hashCode] = myDescriptor;
return myDescriptor;
},
).toList();
}
@override
Future<Uint8List> readCharacteristic(
GattCharacteristic characteristic,
) async {
await _throwWithoutState(CentralState.poweredOn);
final myCharacteristic = characteristic as MyGattCharacteristic;
final myService = myCharacteristic.myService;
final myPeripheral = myService.myPeripheral;
final value = await _myApi.readCharacteristic(
myPeripheral.hashCode,
myService.hashCode,
myCharacteristic.hashCode,
);
return value;
}
@override
Future<void> writeCharacteristic(
GattCharacteristic characteristic, {
required Uint8List value,
required GattCharacteristicWriteType type,
}) async {
await _throwWithoutState(CentralState.poweredOn);
final myCharacteristic = characteristic as MyGattCharacteristic;
final myService = myCharacteristic.myService;
final myPeripheral = myService.myPeripheral;
final typeArgs = type.toMyArgs();
final typeNumber = typeArgs.index;
await _myApi.writeCharacteristic(
myPeripheral.hashCode,
myService.hashCode,
myCharacteristic.hashCode,
value,
typeNumber,
);
}
@override
Future<void> notifyCharacteristic(
GattCharacteristic characteristic, {
required bool state,
}) async {
await _throwWithoutState(CentralState.poweredOn);
final myCharacteristic = characteristic as MyGattCharacteristic;
final myService = myCharacteristic.myService;
final myPeripheral = myService.myPeripheral;
await _myApi.notifyCharacteristic(
myPeripheral.hashCode,
myService.hashCode,
myCharacteristic.hashCode,
state,
);
}
@override
Future<Uint8List> readDescriptor(GattDescriptor descriptor) async {
await _throwWithoutState(CentralState.poweredOn);
final myDescriptor = descriptor as MyGattDescriptor;
final myCharacteristic = myDescriptor.myCharacteristic;
final myService = myCharacteristic.myService;
final myPeripheral = myService.myPeripheral;
final value = await _myApi.readDescriptor(
myPeripheral.hashCode,
myCharacteristic.hashCode,
myDescriptor.hashCode,
);
return value;
}
@override
Future<void> writeDescriptor(
GattDescriptor descriptor, {
required Uint8List value,
}) async {
await _throwWithoutState(CentralState.poweredOn);
final myDescriptor = descriptor as MyGattDescriptor;
final myCharacteristic = myDescriptor.myCharacteristic;
final myService = myCharacteristic.myService;
final myPeripheral = myService.myPeripheral;
await _myApi.writeDescriptor(
myPeripheral.hashCode,
myCharacteristic.hashCode,
myDescriptor.hashCode,
value,
);
}
@override
void onStateChanged(int myStateNumber) {
final myStateArgs = MyCentralStateArgs.values[myStateNumber];
final state = myStateArgs.toState();
if (_state == state) {
return;
}
_state = state;
final eventArgs = CentralStateChangedEventArgs(state);
_stateChangedController.add(eventArgs);
}
@override
void onDiscovered(
MyPeripheralArgs myPeripheralArgs,
int rssi,
MyAdvertisementArgs myAdvertisementArgs,
) {
final myPeripheral = MyPeripheral.fromMyArgs(myPeripheralArgs);
_myPeripherals[myPeripheral.hashCode] = myPeripheral;
final advertisement = myAdvertisementArgs.toAdvertisement();
final eventArgs = CentralDiscoveredEventArgs(
myPeripheral,
rssi,
advertisement,
);
_discoveredController.add(eventArgs);
}
@override
void onPeripheralStateChanged(int myPeripheralKey, bool state) {
final myPeripheral = _myPeripherals[myPeripheralKey];
if (myPeripheral == null) {
return;
}
final eventArgs = PeripheralStateChangedEventArgs(myPeripheral, state);
_peripheralStateChangedController.add(eventArgs);
}
@override
void onCharacteristicValueChanged(int myCharacteristicKey, Uint8List value) {
final myCharacteristic =
_myCharacteristics[myCharacteristicKey] as MyGattCharacteristic;
final eventArgs = GattCharacteristicValueChangedEventArgs(
myCharacteristic,
value,
);
_characteristicValueChangedController.add(eventArgs);
}
}
extension on MyAdvertisementArgs {
Advertisement toAdvertisement() {
final serviceUUIDs = this
.serviceUUIDs
.cast<String>()
.map((uuid) => UUID.fromString(uuid))
.toList();
final serviceData = this.serviceData.cast<String, Uint8List>().map(
(uuid, data) {
final key = UUID.fromString(uuid);
final value = data;
return MapEntry(key, value);
},
);
return Advertisement(
name: name,
manufacturerSpecificData: manufacturerSpecificData.cast<int, Uint8List>(),
serviceUUIDs: serviceUUIDs,
serviceData: serviceData,
);
}
}
extension on MyCentralStateArgs {
CentralState toState() {
return CentralState.values[index];
}
}
extension on GattCharacteristicWriteType {
MyGattCharacteristicWriteTypeArgs toMyArgs() {
return MyGattCharacteristicWriteTypeArgs.values[index];
}
}

View File

@ -0,0 +1,42 @@
import 'package:bluetooth_low_energy_platform_interface/bluetooth_low_energy_platform_interface.dart';
import 'my_api.g.dart';
import 'my_gatt_service.dart';
import 'my_object.dart';
class MyGattCharacteristic extends MyObject implements GattCharacteristic {
final MyGattService myService;
@override
final UUID uuid;
@override
final List<GattCharacteristicProperty> properties;
MyGattCharacteristic(
super.hashCode,
this.myService,
this.uuid,
this.properties,
);
factory MyGattCharacteristic.fromMyArgs(
MyGattService myService,
MyGattCharacteristicArgs myArgs,
) {
final hashCode = myArgs.key;
final uuid = UUID.fromString(myArgs.uuid);
final properties = myArgs.myPropertyNumbers.cast<int>().map(
(myPropertyNumber) {
final myPropertyArgs =
MyGattCharacteristicPropertyArgs.values[myPropertyNumber];
return myPropertyArgs.toProperty();
},
).toList();
return MyGattCharacteristic(hashCode, myService, uuid, properties);
}
}
extension on MyGattCharacteristicPropertyArgs {
GattCharacteristicProperty toProperty() {
return GattCharacteristicProperty.values[index];
}
}

View File

@ -0,0 +1,22 @@
import 'package:bluetooth_low_energy_platform_interface/bluetooth_low_energy_platform_interface.dart';
import 'my_api.g.dart';
import 'my_gatt_characteristic.dart';
import 'my_object.dart';
class MyGattDescriptor extends MyObject implements GattDescriptor {
final MyGattCharacteristic myCharacteristic;
@override
final UUID uuid;
MyGattDescriptor(super.hashCode, this.myCharacteristic, this.uuid);
factory MyGattDescriptor.fromMyArgs(
MyGattCharacteristic myCharacteristic,
MyGattDescriptorArgs myArgs,
) {
final hashCode = myArgs.key;
final uuid = UUID.fromString(myArgs.uuid);
return MyGattDescriptor(hashCode, myCharacteristic, uuid);
}
}

View File

@ -0,0 +1,22 @@
import 'package:bluetooth_low_energy_platform_interface/bluetooth_low_energy_platform_interface.dart';
import 'my_api.g.dart';
import 'my_object.dart';
import 'my_peripheral.dart';
class MyGattService extends MyObject implements GattService {
final MyPeripheral myPeripheral;
@override
final UUID uuid;
MyGattService(super.hashCode, this.myPeripheral, this.uuid);
factory MyGattService.fromMyArgs(
MyPeripheral myPeripheral,
MyGattServiceArgs myArgs,
) {
final hashCode = myArgs.key;
final uuid = UUID.fromString(myArgs.uuid);
return MyGattService(hashCode, myPeripheral, uuid);
}
}

View File

@ -0,0 +1,11 @@
abstract class MyObject {
@override
final int hashCode;
MyObject(this.hashCode);
@override
bool operator ==(Object other) {
return other is MyObject && other.hashCode == hashCode;
}
}

View File

@ -0,0 +1,17 @@
import 'package:bluetooth_low_energy_platform_interface/bluetooth_low_energy_platform_interface.dart';
import 'my_api.g.dart';
import 'my_object.dart';
class MyPeripheral extends MyObject implements Peripheral {
@override
final UUID uuid;
MyPeripheral(super.hashCode, this.uuid);
factory MyPeripheral.fromMyArgs(MyPeripheralArgs myArgs) {
final hashCode = myArgs.key;
final uuid = UUID.fromString(myArgs.uuid);
return MyPeripheral(hashCode, uuid);
}
}

View File

@ -0,0 +1,151 @@
import 'package:pigeon/pigeon.dart';
@ConfigurePigeon(
PigeonOptions(
dartOut: 'lib/src/my_api.g.dart',
dartOptions: DartOptions(),
swiftOut: 'darwin/Classes/MyApi.g.swift',
swiftOptions: SwiftOptions(),
),
)
@HostApi()
abstract class MyCentralControllerHostApi {
@async
MyCentralControllerArgs setUp();
void tearDown();
void startDiscovery();
void stopDiscovery();
@async
void connect(int myPeripheralKey);
@async
void disconnect(int myPeripheralKey);
@async
void discoverGATT(int myPeripheralKey);
List<MyGattServiceArgs> getServices(int myPeripheralKey);
List<MyGattCharacteristicArgs> getCharacteristics(int myServiceKey);
List<MyGattDescriptorArgs> getDescriptors(int myCharacteristicKey);
@async
Uint8List readCharacteristic(
int myPeripheralKey,
int myServiceKey,
int myCharacteristicKey,
);
@async
void writeCharacteristic(
int myPeripheralKey,
int myServiceKey,
int myCharacteristicKey,
Uint8List value,
int myTypeNumber,
);
@async
void notifyCharacteristic(
int myPeripheralKey,
int myServiceKey,
int myCharacteristicKey,
bool state,
);
@async
Uint8List readDescriptor(
int myPeripheralKey,
int myCharacteristicKey,
int myDescriptorKey,
);
@async
void writeDescriptor(
int myPeripheralKey,
int myCharacteristicKey,
int myDescriptorKey,
Uint8List value,
);
}
@FlutterApi()
abstract class MyCentralControllerFlutterApi {
void onStateChanged(int myStateNumber);
void onDiscovered(
MyPeripheralArgs myPeripheralArgs,
int rssi,
MyAdvertisementArgs myAdvertisementArgs,
);
void onPeripheralStateChanged(int myPeripheralKey, bool state);
void onCharacteristicValueChanged(int myCharacteristicKey, Uint8List value);
}
class MyCentralControllerArgs {
final int myStateNumber;
MyCentralControllerArgs(this.myStateNumber);
}
class MyPeripheralArgs {
final int key;
final String uuid;
MyPeripheralArgs(this.key, this.uuid);
}
class MyAdvertisementArgs {
final String? name;
final Map<int?, Uint8List?> manufacturerSpecificData;
final List<String?> serviceUUIDs;
final Map<String?, Uint8List?> serviceData;
MyAdvertisementArgs(
this.name,
this.manufacturerSpecificData,
this.serviceUUIDs,
this.serviceData,
);
}
class MyGattServiceArgs {
final int key;
final String uuid;
MyGattServiceArgs(this.key, this.uuid);
}
class MyGattCharacteristicArgs {
final int key;
final String uuid;
final List<int?> myPropertyNumbers;
MyGattCharacteristicArgs(
this.key,
this.uuid,
this.myPropertyNumbers,
);
}
class MyGattDescriptorArgs {
final int key;
final String uuid;
MyGattDescriptorArgs(this.key, this.uuid);
}
enum MyCentralStateArgs {
unknown,
unsupported,
unauthorized,
poweredOff,
poweredOn,
}
enum MyGattCharacteristicPropertyArgs {
read,
write,
writeWithoutResponse,
notify,
indicate,
}
enum MyGattCharacteristicWriteTypeArgs {
// Write with response
withResponse,
// Write without response
withoutResponse,
// Write with response and waiting for confirmation
// reliable,
}

View File

@ -0,0 +1,31 @@
name: bluetooth_low_energy_darwin
description: iOS and macOS implementation of the bluetooth_low_energy plugin.
version: 2.0.2
homepage: https://github.com/yanshouwang/bluetooth_low_energy
environment:
sdk: ">=3.0.0 <4.0.0"
flutter: ">=3.3.0"
dependencies:
flutter:
sdk: flutter
bluetooth_low_energy_platform_interface: ^2.0.2
dev_dependencies:
flutter_test:
sdk: flutter
flutter_lints: ^2.0.0
pigeon: ^10.1.6
flutter:
plugin:
platforms:
ios:
pluginClass: BluetoothLowEnergyDarwin
sharedDarwinSource: true
dartPluginClass: BluetoothLowEnergyDarwin
macos:
pluginClass: BluetoothLowEnergyDarwin
sharedDarwinSource: true
dartPluginClass: BluetoothLowEnergyDarwin