import Foundation // MARK: - Connection extension DuooomiBleSDK { /// 连接到指定设备。 /// /// 内部会停止扫描、启动协议监听。成功后 `sdk.btState = .connected`,`sdk.connectedDevice` 写入; /// delegate `didConnectDevice` 回调到达。后续可调用 `getVersion` / `getDeviceInfo` / `bind` 等。 /// /// - Parameters: /// - deviceId: 设备 UUID(从 `discoveredDevices.id` 取,对应 `CBPeripheral.identifier.uuidString`) /// - completion: 回调 `Result` /// - 成功:连接上的 `DiscoveredDevice` /// - 失败:`.connectionFailed(...)` / `.serviceNotFound` / `.characteristicNotFound` /// / `.bluetoothNotPoweredOn(...)` / `.permissionDenied` public func connect(deviceId: String, completion: @escaping (Result) -> Void) { stopScan() btState = .connecting BleLog.i("Connecting to \(deviceId)...", "Connect") bleClient.connect(deviceId: deviceId) { [weak self] result in guard let self = self else { return } switch result { case .success(let peripheral): self.protocolService.startListening() let device = DiscoveredDevice( id: peripheral.identifier.uuidString, name: peripheral.name, rssi: 0 ) self.connectedDevice = device self.btState = .connected BleLog.i("Connected: \(device.id)", "Connect") completion(.success(device)) case .failure(let error): self.btState = .idle self.error = error.localizedDescription BleLog.e("Connect failed: \(error.localizedDescription)", "Connect") completion(.failure(error)) } } } /// 断开当前 BLE 连接。 /// /// 同步清空 `sdk.connectedDevice` / `deviceInfo` / `version` / `isActivated`,停止协议监听, /// 取消所有 pending RPC 回调(这些回调会收到 `.notConnected` 失败)。 /// /// - Parameter completion: 回调 `Result` /// - 成功:已断开 /// - 失败:CoreBluetooth 底层错误(极少见) public func disconnect(completion: @escaping (Result) -> Void) { btState = .disconnecting BleLog.i("Disconnect requested", "Connect") protocolService.stopListening() cancelAllPending(error: DuooomiBleError.notConnected) bleClient.disconnect { [weak self] result in guard let self = self else { return } if case .failure(let error) = result { self.error = error.localizedDescription BleLog.e("Disconnect error: \(error.localizedDescription)", "Connect") } self.connectedDevice = nil self.deviceInfo = nil self.version = "" self.isActivated = false self.btState = .disconnected BleLog.i("Disconnected", "Connect") completion(result) } } /// 返回 iOS 系统当前已连接的、和本 SDK 服务 UUID 匹配的设备列表。 /// /// 用于断网后重启 App、设备仍在系统蓝牙连接列表里的快速恢复场景。 /// 不需要先 `scan()`,对每个返回的 `DiscoveredDevice.id` 直接 `connect(deviceId:)` 即可。 /// /// - Returns: 系统已连接的 `DiscoveredDevice` 数组(可能为空) public func getConnectedDevices() -> [DiscoveredDevice] { let list = bleClient.retrieveConnectedDevices() BleLog.d("System-connected devices: \(list.count)", "Connect") return list } }