From af93787ec144dc86b0ca880a2e5a30bfbc25f032 Mon Sep 17 00:00:00 2001 From: Konstantin Polin Date: Sat, 27 Dec 2025 20:37:38 -0800 Subject: [PATCH] Implemented retrieveConnectedPeripherals --- README.md | 29 +++++++++ .../ActorCoreBluetooth/BluetoothCentral.swift | 61 +++++++++++++++++++ 2 files changed, 90 insertions(+) diff --git a/README.md b/README.md index aae2bf4..6726047 100644 --- a/README.md +++ b/README.md @@ -147,6 +147,35 @@ func scanAndConnect() async throws { } ``` +### Retrieving System-Connected Peripherals + +Connect to peripherals that are already connected to the system by other apps or system services: + +```swift +@MainActor +func retrieveConnectedPeripherals() async throws { + let central = BluetoothCentral() + + // Retrieve peripherals already connected to Heart Rate service + let connectedPeripherals = try await central.retrieveConnectedPeripherals( + withServices: ["180D"], // Heart Rate service UUID + timeout: 10.0 + ) + + // Process all successfully connected peripherals + for peripheral in connectedPeripherals { + print("Connected to system peripheral: \(peripheral.name ?? "Unknown")") + + // Work with the peripheral normally + let services = try await peripheral.discoverServices(timeout: 5.0) + print("Discovered \(services.count) services") + } + + // Note: This method uses best-effort approach - if one peripheral fails to connect, + // it will log the error and continue with the remaining peripherals +} +``` + ### Service and Characteristic Discovery Complete discovery with flexible options: diff --git a/Sources/ActorCoreBluetooth/BluetoothCentral.swift b/Sources/ActorCoreBluetooth/BluetoothCentral.swift index cd63f7a..fb89f56 100644 --- a/Sources/ActorCoreBluetooth/BluetoothCentral.swift +++ b/Sources/ActorCoreBluetooth/BluetoothCentral.swift @@ -437,6 +437,67 @@ public final class BluetoothCentral { try await disconnect(peripheral.identifier, timeout: timeout) } + /// Retrieve and connect to peripherals that are already connected at the system level + /// This is useful for peripherals connected by other apps or the system + public func retrieveConnectedPeripherals( + withServices services: [String], + timeout: TimeInterval? = nil + ) async throws -> [ConnectedPeripheral] { + try await ensureCentralManagerInitialized() + + guard let cbCentralManager = cbCentralManager else { + logger?.errorError("Cannot retrieve connected peripherals: CBCentralManager not initialized") + throw BluetoothError.centralManagerNotInitialized + } + + let cbServices = services.compactMap { CBUUID(string: $0) } + let serviceInfo = services.joined(separator: ", ") + + logger?.centralInfo("Retrieving system-connected peripherals", context: [ + "services": serviceInfo, + "timeout": timeout as Any + ]) + + let cbPeripherals = cbCentralManager.retrieveConnectedPeripherals(withServices: cbServices) + + logger?.centralDebug("Found system-connected peripherals", context: [ + "count": cbPeripherals.count, + "peripherals": cbPeripherals.map { $0.name ?? $0.identifier.uuidString }.joined(separator: ", ") + ]) + + guard !cbPeripherals.isEmpty else { + logger?.centralInfo("No system-connected peripherals found for specified services") + return [] + } + + var connectedPeripherals: [ConnectedPeripheral] = [] + + for cbPeripheral in cbPeripherals { + do { + let connected = try await connectToRetrievedPeripheral( + cbPeripheral, + originalName: cbPeripheral.name, + timeout: timeout + ) + connectedPeripherals.append(connected) + } catch { + logger?.connectionWarning("Failed to connect to system-connected peripheral", context: [ + "peripheralName": cbPeripheral.name ?? "Unknown", + "peripheralID": cbPeripheral.identifier.uuidString, + "error": error.localizedDescription + ]) + // Continue with other peripherals rather than failing entirely + } + } + + logger?.centralNotice("Retrieved connected peripherals", context: [ + "requested": cbPeripherals.count, + "successful": connectedPeripherals.count + ]) + + return connectedPeripherals + } + /// Get list of currently connected peripheral IDs public var connectedPeripheralIDs: [UUID] { let ids = Array(connectedPeripherals.keys)