CombineCoreBluetooth
CombineCoreBluetooth是一个库,它连接了Apple的CoreBluetooth
框架和Apple的Combine
框架,使得您可以订阅执行蓝牙操作,同时在订阅操作结果的发布者时进行,而不是依赖于实施代理和手动筛选所需的特定结果。
要求
- iOS 13, tvOS 13, macOS 10.15, 或 watchOS 6
- Xcode 12 或更高版本
- Swift 5.3 或更高版本
安装
Swift Package Manager
将此行添加到您的 Package.swift 依赖项列表中
.package(name: "CombineCoreBluetooth", url: "https://github.com/StarryInternet/CombineCoreBluetooth.git", from: "0.3.0"),
Cocoapods
将此行添加到您的 Podfile 中
pod 'CombineCoreBluetooth'
Carthage
将此行添加到您的 Cartfile 中
github "StarryInternet/CombineCoreBluetooth"
用法
这个库深受 pointfree.co 的设计依赖项方法 启发,但进行了一些定制。许多异步操作会返回自己的 Publisher
或公开它们的长期存在的可以订阅的发布者。
这个库除了实现本库提供一个以组合为中心的API所需的状态外,不维护任何其他状态。这意味着您必须维护任何必要的状态,包括保留通过在 CentralManager
类型中找到并连接的任何 Peripheral
。
要扫描外设,类似平铺 CoreBluetooth,您调用 scanForPeripherals(withServices:options:)
方法。然而,在这个库的 CentralManager
类型上,这返回了一个 PeripheralDiscovery
值的发布者。如果您想要存储一个外设以便以后使用,您可以通过以下方式订阅返回的发布者
let serviceID = CBUUID(string: "0123")
centralManager.scanForPeripherals(withServices: [serviceID])
.first()
.assign(to: \.peripheralDiscovery, on: self) // property of type PeripheralDiscovery
.store(in: &cancellables)
要进行类似从特性中获取值的操作,例如,您可以对Peripheral
类型调用以下方法,并订阅生成的Publisher
// use whatever ids your peripheral advertises here
let characteristicID = CBUUID(string: "4567")
peripheralDiscovery.peripheral
.readValue(forCharacteristic: characteristicID, inService: serviceID)
.sink(receiveCompletion: { completion in
// handle any potential errors here
}, receiveValue: { data in
// handle data from characteristic here, or add more publisher methods to map and transform it.
})
.store(in: &cancellables)
在readValue
中返回的发布者将只会将匹配服务和服务特性ID的值发送给任何订阅者,因此您无需自己处理任何过滤逻辑。请注意,如果Peripheral
从未通过蓝牙从该特性接收到值,则它永远不会将值发送给发布者,所以如果您的用例需要,您可能需要添加超时。
注意事项
CoreBluetooth
中的所有主要类型都应在此库中可用,并且封装在其自己的类型中以提供以Combine
为中心的API。此库已在生产中对大多数与CentralManager
相关的操作进行了测试。还支持使用PeripheralManager
类型作为蓝牙外围设备的应用程序,但该方面尚未进行严格的测试。
截至版本0.2,所有写入特性操作都期望一个响应,即使这些特性没有被外围设备指定在写入完成后响应;这意味着如果尝试写入不响应的特性,发布者永远不会完成。在此改变之前,您需负责管理具有这些属性的写入特性发布者的生命周期。