Ecosyste.ms: Awesome
An open API service indexing awesome lists of open source software.
https://github.com/exphat/swiftbluetooth
📲 CoreBluetooth API's for modern Swift
https://github.com/exphat/swiftbluetooth
async bluetooth bluetooth-low-energy corebluetooth ios swift
Last synced: 12 days ago
JSON representation
📲 CoreBluetooth API's for modern Swift
- Host: GitHub
- URL: https://github.com/exphat/swiftbluetooth
- Owner: exPHAT
- License: mit
- Created: 2023-08-29T18:27:58.000Z (about 1 year ago)
- Default Branch: master
- Last Pushed: 2024-06-18T17:44:38.000Z (5 months ago)
- Last Synced: 2024-10-03T12:33:32.396Z (about 1 month ago)
- Topics: async, bluetooth, bluetooth-low-energy, corebluetooth, ios, swift
- Language: Swift
- Homepage:
- Size: 207 KB
- Stars: 42
- Watchers: 6
- Forks: 7
- Open Issues: 6
-
Metadata Files:
- Readme: README.md
- License: LICENSE
Awesome Lists containing this project
README
![SwiftBluetooth](.github/assets/logo.jpg)
Easily interface with Bluetooth peripherals in new or existing projects through modern async Swift API's.
[![](https://img.shields.io/endpoint?url=https%3A%2F%2Fswiftpackageindex.com%2Fapi%2Fpackages%2FexPHAT%2FSwiftBluetooth%2Fbadge%3Ftype%3Dswift-versions)](https://swiftpackageindex.com/exPHAT/SwiftBluetooth)
[![](https://img.shields.io/endpoint?url=https%3A%2F%2Fswiftpackageindex.com%2Fapi%2Fpackages%2FexPHAT%2FSwiftBluetooth%2Fbadge%3Ftype%3Dplatforms)](https://swiftpackageindex.com/exPHAT/SwiftBluetooth)## Features
- [x] Parity with existing `CoreBluetooth` APIs for easy, incremental migration of existing projects
- [x] Modern, async-await API for discovery, connection, read/write, and more
- [x] Alternate callback-based API for codebases not using Swift Concurrency
- [x] Subscribe to peripheral discoveries, value updates, and more through `AsyncStream`
- [x] Easy await-ing of `CentralManager` state
- [x] Staticly typed characteristics
- [x] Thread safe
- [x] Zero inherited dependencies
- [x] Tested with included `SwiftBluetoothMock` library## Examples
[API Documentation.](https://swiftpackageindex.com/exPHAT/SwiftBluetooth/1.0.0/documentation/)
#### Complete example
Async API's make the entire Bluetooth lifecycle much simpler, using method names you're already familiar with from CoreBluetooth.
```swift
import SwiftBluetoothlet central = CentralManager()
try await central.waitUntilReady()// Find and connect to the first available peripheral
let peripheral = await central.scanForPeripherals(withServices: [myService]).first!
try await central.connect(peripheral, timeout: connectionTimeout)// Discover services and characteristics
let service = try await peripheral.discoverServices([myService]).first!
let _ = try await peripheral.discoverCharacteristics([.someCharacteristic], for: service)// Read data directly from your characteristic
let value = try await peripheral.readValue(for: .someCharacteristic)central.cancelPeripheralConnection(peripheral)
```#### Callbacks
Stock CoreBluetooth methods now also have an additional overload that takes a completionHandler for projects not using Swift Concurrency.
```swift
central.connect(peripheral) { result in
if result == .failure(let error) {
// Issue connecting
return
}// Connected!
}
```
> Methods often now have 3 overloads. One marked `async`, one with a `completionHandler`, and the original CoreBluetooth verision. Meaning you can choose whichever is most convienient at the time.#### Stream discovered peripherals
Some operations (like scanning) conform to `AsyncStream`, meaning you can use for-await-in loops to iterate over new items.
```swift
for await peripheral in await central.scanForPeripherals() {
print("Discovered:", peripheral.name ?? "Unknown")
}
```#### Defining characteristics
Characteristics can be staticly defined on the stock `Characteristic` type, which removes the burden of keeping track of `CBCharacteristic` instances around your app.
```swift
extension Characteristic {
static let someCharacteristic = Self("00000000-0000-0000-0000-000000000000")
}// Use those characteristics later on your peripheral
try await myPeripheral.readValue(for: .someCharacteristic)
```#### Watching with callbacks
Peristent tasks return a `CancellableTask` that needs to be cancelled when you're done.
```swift
let task = central.scanForPeripherals { peripheral in
print("Discovered:", peripheral.name ?? "Unknown")
}// At some point later, cancel the task to stop scanning
task.cancel()
```
> **Note**
Calling `central.stopScan()` will also cancel any peripheral scanning tasks#### Migrate existing projects
Existing projects that already use `CoreBluetooth` can immediately get started by typealiasing the stock types. Afterwards, you can adopt async API's at your own pace.
```swift
import CoreBluetooth
import SwiftBluetooth // Add this// Override existing CoreBluetooth classes to use SwiftBluetooth
typealias CBCentralManager = SwiftBluetooth.CentralManager
typealias CBCentralManagerDelegate = SwiftBluetooth.CentralManagerDelegate
typealias CBPeripheral = SwiftBluetooth.Peripheral
typealias CBPeripheralDelegate = SwiftBluetooth.PeripheralDelegate// Your existing code should continue to work as normal.
// But now you have access to all the new API's!
```## Install
#### Xcode
Add `https://github.com/exPHAT/SwiftBluetooth.git` in the ["Swift Package Manager" tab.](https://developer.apple.com/documentation/xcode/adding-package-dependencies-to-your-app)
#### Swift Package Manager
Add SwiftBluetooth as a dependency in your `Package.swift` file:
```swift
let package = Package(
...
dependencies: [
// Add the package to your dependencies
.package(url: "https://github.com/exPHAT/SwiftBluetooth.git", branch: "master"),
],
...
targets: [
// Add SwiftBluetooth as a dependency on any target you want to use it in
.target(name: "MyTarget",
dependencies: [.byName(name: "SwiftBluetooth")])
]
...
)
```