Files
bluetooth_low_energy/bluetooth_low_energy_darwin/darwin/Classes/MyAPI.swift
渐渐被你吸引 108b6a804f 6.0.0 (#74)
* 调整接口

* 临时提交

* 重构 Android 平台代码

* 临时提交

* 临时提交

* Android 6.0.0-dev.0

* 临时提交

* 实现 Windows 接口

* windows-6.0.0-dev.0

* Darwin 6.0.0-dev.0

* 临时提交

* 1

* 临时提交

* 调整接口

* windows-6.0.0-dev.1

* 临时提交

* interface-6.0.0-dev.7

* interface-6.0.0-dev.8

* 临时提交

* windows-6.0.0-dev.2

* 删除多余脚本

* interface-6.0.0-dev.9

* 临时提交

* 临时提交

* interface-6.0.0-dev.10

* android-6.0.0-dev.1

* windows-6.0.0-dev.3

* 临时提交

* interface-6.0.0-dev.11

* windows-6.0.0-dev.4

* 更新 pubspec.lock

* 1

* interface-6.0.0-dev.12

* interface-6.0.0-dev.13

* interface-6.0.0-dev.14

* 临时提交

* interface-6.0.0-dev.15

* 临时提交

* interface-6.0.0-dev.16

* android-6.0.0-dev.2

* 临时提交

* windows-6.0.0-dev.5

* 临时提交

* 临时提交

* windows-6.0.0-dev.6

* 优化注释和代码样式

* 优化代码

* 临时提交

* 实现 Dart 接口

* darwin-6.0.0-dev.0

* linux-6.0.0-dev.0

* 修复已知问题

* 修复问题

* 6.0.0-dev.0

* 修改包名

* 更新版本

* 移除原生部分

* 临时提交

* 修复问题

* 更新 pigeon 19.0.0

* 更新 README,添加迁移文档

* linux-6.0.0-dev.1

* 解析扫描回复和扩展广播

* 修复 googletest 版本警告问题

* Use centralArgs instead of addressArgs

* interface-6.0.0-dev.18

* android-6.0.0-dev.4

* linux-6.0.0-dev.2

* windows-6.0.0-dev.8

* darwin-6.0.0-dev.2

* 6.0.0-dev.1

* Update LICENSE

* clang-format

* Combine ADV_IND and SCAN_RES

* TEMP commit: update exampe

* Adjust advertisement combine logic

* Implement `MyPeripheralMananger` on Windows

* Added NuGet auto download and scan for names on peripheral (#67)

* fetch nuget using other technique

* move FetchContent to right location in CMakeLists.txt

* also added hash for googletest

---------

Co-authored-by: Kevin De Keyser <kevin@dekeyser.ch>

* Fix errors.

* Check BluetoothAdapter role supported state and implement PeripheralManager on Flutter side.

* Sort code

* Fix known errors

* interface-6.0.0-dev.19

* windows-6.0.0-dev.9

* Optimize example

* android-6.0.0-dev.5

* Optimize the Adverrtisement BottomSheet.

* linux-6.0.0-dev.3

* Update dependency

* Fix example errors.

* Temp commit.

* darwin-6.0.0-dev.3

* 6.0.0-dev.2

* Update README.md

* 6.0.0

* darwin-6.0.0-dev.4

* android-6.0.0-dev.6

* 6.0.0-dev.3

* Update docs.

* interface-6.0.0

* android-6.0.0

* darwin-6.0.0

* linux-6.0.0

* windows-6.0.0

* 6.0.0

* Update dependency

---------

Co-authored-by: Kevin De Keyser <dekeyser.kevin97@gmail.com>
Co-authored-by: Kevin De Keyser <kevin@dekeyser.ch>
2024-06-04 00:44:39 +08:00

304 lines
9.5 KiB
Swift

//
// MyApi.swift
// bluetooth_low_energy_darwin
//
// Created by on 2023/9/28.
//
import Foundation
import CoreBluetooth
#if os(iOS)
import Flutter
#elseif os(macOS)
import FlutterMacOS
#else
#error("Unsupported platform.")
#endif
// ToObj
extension [MyGATTCharacteristicPropertyArgs] {
func toProperties() -> CBCharacteristicProperties {
var properties: CBCharacteristicProperties = []
for args in self {
switch args {
case .read:
properties.insert(.read)
case .write:
properties.insert(.write)
case .writeWithoutResponse:
properties.insert(.writeWithoutResponse)
case .notify:
properties.insert(.notify)
case .indicate:
properties.insert(.indicate)
}
}
return properties
}
}
extension [MyGATTCharacteristicPermissionArgs] {
func toPermissions() -> CBAttributePermissions {
var permissions: CBAttributePermissions = []
for args in self {
switch args {
case .read:
permissions.insert(.readable)
case .readEncrypted:
permissions.insert(.readEncryptionRequired)
case .write:
permissions.insert(.writeable)
case .writeEncrypted:
permissions.insert(.writeEncryptionRequired)
}
}
return permissions
}
}
extension MyGATTCharacteristicWriteTypeArgs {
func toWriteType() -> CBCharacteristicWriteType {
switch self {
case .withResponse:
return .withResponse
case .withoutResponse:
return .withoutResponse
}
}
}
extension MyATTErrorArgs {
func toError() -> CBATTError.Code {
switch self {
case .success:
return .success
case .invalidHandle:
return .invalidHandle
case .readNotPermitted:
return .readNotPermitted
case .writeNotPermitted:
return .writeNotPermitted
case .invalidPDU:
return .invalidPdu
case .insufficientAuthentication:
return .insufficientAuthentication
case .requestNotSupported:
return .requestNotSupported
case .invalidOffset:
return .invalidOffset
case .insufficientAuthorization:
return .insufficientAuthorization
case .prepareQueueFull:
return .prepareQueueFull
case .attributeNotFound:
return .attributeNotFound
case .attributeNotLong:
return .attributeNotLong
case .insufficientEncryptionKeySize:
return .insufficientEncryptionKeySize
case .invalidAttributeValueLength:
return .invalidAttributeValueLength
case .unlikelyError:
return .unlikelyError
case .insufficientEncryption:
return .insufficientEncryption
case .unsupportedGroupType:
return .unsupportedGroupType
case .insufficientResources:
return .insufficientResources
}
}
}
extension MyAdvertisementArgs {
func toAdvertisement() -> [String : Any] {
// CoreBluetooth only support `CBAdvertisementDataLocalNameKey` and `CBAdvertisementDataServiceUUIDsKey`
// see https://developer.apple.com/documentation/corebluetooth/cbperipheralmanager/1393252-startadvertising
var advertisement = [String: Any]()
if nameArgs != nil {
let name = nameArgs!
advertisement[CBAdvertisementDataLocalNameKey] = name
}
if !serviceUUIDsArgs.isEmpty {
let serviceUUIDs = serviceUUIDsArgs.map { serviceUUIDArgs in serviceUUIDArgs!.toCBUUID() }
advertisement[CBAdvertisementDataServiceUUIDsKey] = serviceUUIDs
}
return advertisement
}
}
extension MyMutableGATTDescriptorArgs {
func toDescriptor() -> CBMutableDescriptor {
let type = uuidArgs.toCBUUID()
let value = valueArgs?.data
return CBMutableDescriptor(type: type, value: value)
}
}
extension MyMutableGATTCharacteristicArgs {
func toCharacteristic() -> CBMutableCharacteristic {
let type = uuidArgs.toCBUUID()
let propertiesArgs = propertyNumbersArgs.map { propertyNumberArgs in
let propertyNumber = propertyNumberArgs!.toInt()
return MyGATTCharacteristicPropertyArgs(rawValue: propertyNumber)!
}
let properties = propertiesArgs.toProperties()
let value = valueArgs?.data
let permissionsArgs = permissionNumbersArgs.map { permissionNumberArgs in
let permissionNumber = permissionNumberArgs!.toInt()
return MyGATTCharacteristicPermissionArgs(rawValue: permissionNumber)!
}
let permissions = permissionsArgs.toPermissions()
return CBMutableCharacteristic(type: type, properties: properties, value: value, permissions: permissions)
}
}
extension MyMutableGATTServiceArgs {
func toService() -> CBMutableService {
let type = uuidArgs.toCBUUID()
let primary = isPrimaryArgs
return CBMutableService(type: type, primary: primary)
}
}
extension Int64 {
func toInt() -> Int {
return Int(self)
}
}
extension String {
func toCBUUID() -> CBUUID {
return CBUUID(string: self)
}
}
// ToArgs
extension CBManagerState {
func toArgs() -> MyBluetoothLowEnergyStateArgs {
switch self {
case .resetting:
return .resetting
case .unsupported:
return .unsupported
case .unauthorized:
return .unauthorized
case .poweredOff:
return .poweredOff
case .poweredOn:
return .poweredOn
default:
return .unknown
}
}
}
extension [String: Any] {
func toAdvertisementArgs() -> MyAdvertisementArgs {
let nameArgs = self[CBAdvertisementDataLocalNameKey] as? String
let serviceUUIDs = self[CBAdvertisementDataServiceUUIDsKey] as? [CBUUID] ?? []
let serviceUUIDsArgs = serviceUUIDs.map { uuid in uuid.uuidString }
let serviceData = self[CBAdvertisementDataServiceDataKey] as? [CBUUID: Data] ?? [:]
let serviceDataArgsKeyWithValues = serviceData.map { (uuid, data) in
let uuidArgs = uuid.uuidString
let dataArgs = FlutterStandardTypedData(bytes: data)
return (uuidArgs, dataArgs)
}
let serviceDataArgs = [String?: FlutterStandardTypedData?](uniqueKeysWithValues: serviceDataArgsKeyWithValues)
let manufacturerData = self[CBAdvertisementDataManufacturerDataKey] as? Data
let manufacturerSpecificDataArgs = manufacturerData == nil ? nil : FlutterStandardTypedData(bytes: manufacturerData!)
return MyAdvertisementArgs(nameArgs: nameArgs, serviceUUIDsArgs: serviceUUIDsArgs, serviceDataArgs: serviceDataArgs, manufacturerSpecificDataArgs: manufacturerSpecificDataArgs)
}
}
extension CBCentral {
func toArgs() -> MyCentralArgs {
let uuidArgs = identifier.toArgs()
return MyCentralArgs(uuidArgs: uuidArgs)
}
}
extension CBPeripheral {
func toArgs() -> MyPeripheralArgs {
let uuidArgs = identifier.toArgs()
return MyPeripheralArgs(uuidArgs: uuidArgs)
}
}
extension CBDescriptor {
func toArgs() -> MyGATTDescriptorArgs {
let hashCodeArgs = hash.toInt64()
let uuidArgs = uuid.toArgs()
return MyGATTDescriptorArgs(hashCodeArgs: hashCodeArgs, uuidArgs: uuidArgs)
}
}
extension CBCharacteristic {
func toArgs() -> MyGATTCharacteristicArgs {
let hashCodeArgs = hash.toInt64()
let uuidArgs = uuid.toArgs()
let propertyNumbersArgs = properties.toArgs().map { args in args.rawValue.toInt64() }
let descriptorsArgs = descriptors?.map { descriptor in descriptor.toArgs() } ?? []
return MyGATTCharacteristicArgs(hashCodeArgs: hashCodeArgs, uuidArgs: uuidArgs, propertyNumbersArgs: propertyNumbersArgs, descriptorsArgs: descriptorsArgs)
}
}
extension CBCharacteristicProperties {
func toArgs() -> [MyGATTCharacteristicPropertyArgs] {
var args = [MyGATTCharacteristicPropertyArgs]()
if contains(.read) {
args.append(.read)
}
if contains(.write) {
args.append(.write)
}
if contains(.writeWithoutResponse) {
args.append(.writeWithoutResponse)
}
if contains(.notify) {
args.append(.notify)
}
if contains(.indicate) {
args.append(.indicate)
}
return args
}
}
extension CBService {
func toArgs() -> MyGATTServiceArgs {
let hashCodeArgs = hash.toInt64()
let uuidArgs = uuid.toArgs()
let isPrimaryArgs = isPrimary
let includedServicesArgs = includedServices?.map { includedService in includedService.toArgs() } ?? []
let characteristicsArgs = characteristics?.map { characteristic in characteristic.toArgs() } ?? []
return MyGATTServiceArgs(hashCodeArgs: hashCodeArgs, uuidArgs: uuidArgs, isPrimaryArgs: isPrimaryArgs, includedServicesArgs: includedServicesArgs, characteristicsArgs: characteristicsArgs)
}
}
extension Int {
func toInt64() -> Int64 {
return Int64(self)
}
}
extension UUID {
func toArgs() -> String {
return uuidString.lowercased()
}
}
extension CBUUID {
func toArgs() -> String {
return uuidString.lowercased()
}
}
extension UInt16 {
var data: Data {
var bytes = self
return Data(bytes: &bytes, count: MemoryLayout<UInt16>.size)
}
}