Find, connect and subscribe to Bluetooth LE peripherals without the hard works.
Integrates CoreBluetooth
with CoreData
and CloudKit
. Stores last known data and meta data of subscribed Bluetooth peripherals in CoreData
database and synchronized onto iCloud
(requires iOS 13.0+, watchOS 6.0+, macOS 10.15+ or tvOS 13.0+).
From iOS 13.0+, watchOS 6.0+, macOS 10.15+ or tvOS 13.0+, no delegate needed, with Apple's feature-rich Combine
framework, start listening to Bluetooth devices with minimum one line of codes:
BluetoothThingManager(subscriptions: [Subscription], useCoreData: Bool, useCloudKit: Bool).newDiscoveryPublisher.sink { // your codes here }
import BluetoothThing
Subscribe to GATT services or GATT Characteristics
Find GATT UUIDs here: https://www.bluetooth.com/specifications/gatt/services/
let subscriptions = [
Subscription(service: "180A"), // Device Information
Subscription(service: "180F" , "2A19") // Battery Level
]
CoreData
Storage with iCloud
sync (requires iCloud and remote notification background mode capability)
@available(iOS 13.0, watchOS 6.0, macOS 10.15, tvOS 13.0, *)
BluetoothThingManager(delegate: BluetoothThingManagerDelegate, subscriptions: [Subscription], useCoreData: Bool, useCloudKit: Bool)
// No delegate needed for Combine Publisher
@available(iOS 13.0, watchOS 6.0, macOS 10.15, tvOS 13.0, *)
BluetoothThingManager(subscriptions: [Subscription], useCoreData: Bool, useCloudKit: Bool)
CoreData
local Storage for older versions
let btManager = BluetoothThingManager(delegate: BluetoothThingManagerDelegate, subscriptions: [Subscription], useCoreData: Bool)
Combine
Publisher available from macOS 10.15, iOS 13.0, tvOS 13.0, watchOS 6.0, No delegate needed.
@available(macOS 10.15, iOS 13.0, tvOS 13.0, watchOS 6.0, *)
public var thingsPublisher: CurrentValueSubject<Set<BluetoothThing>, Never>
@available(macOS 10.15, iOS 13.0, tvOS 13.0, watchOS 6.0, *)
public var newDiscoveryPublisher: PassthroughSubject<BluetoothThing, Never>
@available(macOS 10.15, iOS 13.0, tvOS 13.0, watchOS 6.0, *)
public func thingsPublisher(with serviceUUIDs: CBUUID...) -> AnyPublisher<Set<BluetoothThing>, Never>
@available(macOS 10.15, iOS 13.0, tvOS 13.0, watchOS 6.0, *)
public func thingsPublisher<S: Sequence>(with serviceUUIDs: S) -> AnyPublisher<Set<BluetoothThing>, Never> where S.Element == CBUUID
@available(macOS 10.15, iOS 13.0, tvOS 13.0, watchOS 6.0, *)
public func thingsPublisher(with services: BTService...) -> AnyPublisher<Set<BluetoothThing>, Never>
@available(macOS 10.15, iOS 13.0, tvOS 13.0, watchOS 6.0, *)
public func thingsPublisher<S: Sequence>(with services: S) -> AnyPublisher<Set<BluetoothThing>, Never> where S.Element == BTService
Listen to discovered device:
@available(macOS 10.15, iOS 13.0, tvOS 13.0, watchOS 6.0, *)
public var advertisementDataPublisher: CurrentValueSubject<[String : Any], Never>
@available(macOS 10.15, iOS 13.0, tvOS 13.0, watchOS 6.0, *)
public var characteristicsPublisher: CurrentValueSubject<[BTCharacteristic: Data], Never>
Implement BluetoothThingManagerDelegate
protocol BluetoothThingManagerDelegate {
func bluetoothThingManager(_ manager: BluetoothThingManager, didChangeState state: BluetoothState)
func bluetoothThingManager(_ manager: BluetoothThingManager, didFindThing thing: BluetoothThing, rssi: NSNumber)
func bluetoothThingManager(_ manager: BluetoothThingManager, didLoseThing thing: BluetoothThing)
func bluetoothThingManager(_ manager: BluetoothThingManager, didFailToConnect thing: BluetoothThing, error: Error?)
func bluetoothThing(_ thing: BluetoothThing, didChangeState state: ConnectionState)
func bluetoothThing(_ thing: BluetoothThing, didChangeRSSI rssi: NSNumber)
func bluetoothThing(_ thing: BluetoothThing, didUpdateValue value: Data?, for characteristic: BTCharacteristic, subscription: BTSubscription?)
}
Retrive Things
let thing = btManager.things.first
Methods
@available(macOS 10.15, iOS 13.0, tvOS 13.0, watchOS 6.0, *)
thing.connect(pending:) async throws
thing.connect() // Can be called anytime, will connect once comes in range
thing.disconnect()
thing.forget() // remove local storage
thing.read(characteristic:) // read once, no notify
thing.subscribe(characteristic:) // get notified when data changes
thing.write(characteristic:) // write to characteristic