CombineCoreBluetooth

CI GitHub

CombineCoreBluetooth 是一个库,它桥接了 Apple 的 CoreBluetooth 框架和 Apple 的 Combine 框架,从而可以订阅执行蓝牙操作,同时订阅这些操作结果的 Publisher,而不是依赖于实现委托并手动过滤所需的結果。

要求

(如果您使用 Carthage,或者如果您想打开项目来玩演示应用程序,您将需要使用 Xcode 16)

安装

Swift Package Manager

将此行添加到您的 Package.swift 文件中的 dependencies 列表:

.package(name: "CombineCoreBluetooth", url: "https://github.com/StarryInternet/CombineCoreBluetooth.git", from: "0.8.0"),

Cocoapods

将此行添加到您的 Podfile 文件:

pod 'CombineCoreBluetooth'

Carthage

将此行添加到您的 Cartfile 文件:

github "StarryInternet/CombineCoreBluetooth"

用法

该库深受 pointfree.co 的方法 的启发,用于设计依赖项,但进行了一些自定义。许多异步操作会返回它们自己的 Publisher 或公开您可以订阅的长期存在的 publisher。

除了启用该库以提供以 Combine 为中心的 API 所需的内容之外,该库不维护任何其他状态。 这意味着您负责维护任何必要的状态,包括持有通过 CentralManager 类型发现和连接到的任何 Peripheral

要扫描外围设备,就像在普通的 CoreBluetooth 中一样,您调用 scanForPeripherals(withServices:options:) 方法。但是,在该库的 CentralManager 类型上,它返回 PeripheralDiscovery 值的 publisher。如果您想存储外围设备以供以后使用,您可以订阅返回的 publisher,如下所示:

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 中返回的 publisher 只会将与服务和特征 ID 匹配的值传递给任何订阅者,因此您无需担心任何过滤逻辑。请注意,如果 Peripheral 从未通过蓝牙从此特征接收到值,它将永远不会将值发送到 publisher 中,因此如果您的用例需要,您可能需要添加超时。

注意事项

CoreBluetooth 中的所有主要类型都应该在该库中可用,包装在它们自己的类型中以提供以 Combine 为中心的 API。该库已经在生产环境中针对大多数与 CentralManager 相关的操作进行了测试。使用 PeripheralManager 类型也支持充当蓝牙外围设备的应用程序,但那方面没有经过严格的测试。