Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Support retrieving known Peripherals (#38)
# Support retrieving Peripherals ## ♻️ Current situation & Problem SpeziBluetooth is currently optimized for device discovery and ad-hoc connection establishment. However, when dealing with device pairing, one typically scans for nearby devices once and saving the peripheral identifier and perform long running connection attempts (e.g., calling [`retrievePeripherals(withidentifiers:)`](https://developer.apple.com/documentation/corebluetooth/cbcentralmanager/retrieveperipherals(withidentifiers:)) and calling connect()). Connecting a peripheral does not time out and is therefore the most efficient way of establishing Bluetooth connecting with a set of known Bluetooth devices. To support this use case, some modifications have been made to the underlying SpeziBluetooth infrastructure. New mechanisms were introduced to retrieve known peripherals (`BluetoothManager/retrievePeripheral(for:with:)` and `Bluetooth/retrieveDevice(for:as:)`). These device instances can stay allocated and SpeziBluetooth automatically frees resources once the framework user deallocates the peripheral instances. Several changes to the lifecycle handling of `BluetoothPeripheral`s and `BluetoothDevice`s have been made to support this new interfaces (e.g., carefully managing when objects are kept as strong references and when to reuse objects when, e.g., the same instance is getting discovered at the same time). ### SpeziDevices SpeziDevices is an upcoming library to encapsulates a lot of standardized device interactions. This PR is driven by a lot of requirements of this library. ## :gear: Release Notes * Support retrieving known peripherals using `BluetoothManager/retrievePeripheral(for:with:)` and `Bluetooth/retrieveDevice(for:as:)`. * The `BluetoothViews` target was removed and integrated into the `SpeziDevicesUI` of the SpezIDevices framework (see StanfordSpezi/SpeziDevices#1, **Breaking**). * The `BluetoothServices` target was renamed to `SpeziBluetoothServices` for more consistency (**Breaking**). * Add `accessory` discovery criteria. * New `nearby` and `lastActivity` state properties for peripherals and devices. * The peripheral name is now preferred with the `name` property and the `localName` property can now be accessed individually on a peripheral (**Breaking**). * Internally restructure discovery state into an `DiscoverySession` for better code overview. * Configuration options (like minimumRSSI and advertisementStaleInterval) are now passed directly to the `scanNearbyDevices(...)` methods and modifiers allowing for more dynamic configuration. * Adding `Bluetooth/stateSubscription` and `BluetoothManager/stateSubscription` to receive an AsyncStream of `BluetoothState` changes useful when required to observe CBCentral changes. * Adding `CharacteristicAccessor/subscription` and `DeviceStateAccessor/subscription` properties to receive an AsyncStream of changes to the characteristic value or device state. * `onChange(initial:perform:)` methods now must not be set up in the initializer anymore and must not create strong self references. Instead setup onChange handlers in the `configure()` method and make sure to weakly capture `self`. Calling `onChange(initial:perform:)` method in the initializer results in a runtime crash with the error message providing a migration guide. * New `powerOn()` and `powerOff()` methods to manually control `CBCentralManager` allocation. * Fixed an issue where characteristic access continuations where accidentally leaked. * Add new `ManufacturerIdentifier` model supporting parsing of manufacturer data in the advertisement. * Added `ConnectedDevices` environment model to retrieve all connected devices from the SwiftUI environment. * Add `Codable` conformance to all Characteristics. This PR contains breaking changes, requiring a major version bump. ## :books: Documentation Documentation was updated to reflect changed symbols (README currently points to 404 pages). Retrieving devices was documented with a small code examples. ## :white_check_mark: Testing Existing tests verify that refactoring did not break existing infrastructure. Additional test case was added to test retrieving peripherals and ensuring the new reference semantics do not break and peripherals are properly and expectedly deallocated. ## :pencil: Code of Conduct & Contributing Guidelines By submitting creating this pull request, you agree to follow our [Code of Conduct](https://github.com/StanfordSpezi/.github/blob/main/CODE_OF_CONDUCT.md) and [Contributing Guidelines](https://github.com/StanfordSpezi/.github/blob/main/CONTRIBUTING.md): - [x] I agree to follow the [Code of Conduct](https://github.com/StanfordSpezi/.github/blob/main/CODE_OF_CONDUCT.md) and [Contributing Guidelines](https://github.com/StanfordSpezi/.github/blob/main/CONTRIBUTING.md).
- Loading branch information