SwiftyBluetooth
基于闭包的 CoreBluetooth API。
特性
- 替换每个
CBCentralManager
和CBPeripheral
操作的基于代理的接口为基于闭包的接口。 - CBCentralManager 状态变化和状态恢复的通知。
- CBPeripheral 名称更新、特征值更新和服务更新的事件通知。
- 每次蓝牙操作都有精确的错误和保证的超时。
- 如果需要,将自动连接到 CBPeripheral 并尝试发现进行读取或写入操作所需的 BLE 服务和特征。
使用方法
库中有2个重要的类
Central
类,是一个围绕CBCentralManager
的单例包装器,用于通过闭包回调扫描外围设备并恢复之前的会话。Peripheral
类,是一个围绕CBPeripheral
的包装器,用于通过闭包回调调用CBPeripheral
函数。
以下是几个可能对你感兴趣的操作示例。
扫描外围设备
通过调用scanWithTimeout(...)
并传递以秒为单位的timeout
和callback
闭包来扫描外围设备,该闭包关闭以接收Peripheral
结果回调以及扫描状态的更新
// You can pass in nil if you want to discover all Peripherals
SwiftyBluetooth.scanForPeripherals(withServiceUUIDs: nil, timeoutAfter: 15) { scanResult in
switch scanResult {
case .scanStarted:
// The scan started meaning CBCentralManager scanForPeripherals(...) was called
case .scanResult(let peripheral, let advertisementData, let RSSI):
// A peripheral was found, your closure may be called multiple time with a .ScanResult enum case.
// You can save that peripheral for future use, or call some of its functions directly in this closure.
case .scanStopped(let error):
// The scan stopped, an error is passed if the scan stopped unexpectedly
}
}
注意,回调闭包可以被调用多次,但总是从包含.scanStarted
和.scanStopped
结果的回调开始和结束。对于扫描期间找到的每个唯一的外围设备,您的回调都将被调用,以.scanResult
的形式。
连接外围设备
peripheral.connect { result in
switch result {
case .success:
break // You are now connected to the peripheral
case .failure(let error):
break // An error happened while connecting
}
}
从外围设备的服务特征读取
如果您已知要读取的特征和服务UUID,则一旦找到外围设备,就可以立即按照以下方式从它那里读取
peripheral.readValue(ofCharacWithUUID: "2A29", fromServiceWithUUID: "180A") { result in
switch result {
case .success(let data):
break // The data was read and is returned as an NSData instance
case .failure(let error):
break // An error happened while attempting to read the data
}
}
这将根据需要连接到外围设备,并确保在从匹配characteristicUUID
的特征读取之前发现所需的特征和服务。如果无法检索特征/服务,您将收到一个指定哪一个特征/服务找不到的错误。
如果有一个对CBCharacteristic
的引用,您可以直接使用该特征读取
peripheral.readValue(ofCharac: charac) { result in
switch result {
case .success(let data):
break // The data was read and is returned as a Data instance
case .failure(let error):
break // An error happened while attempting to read the data
}
}
向外围设备服务的特征写入
如果您已知想要写入的特征和服务的UUID,一旦找到外围设备,就可以直接像这样向该特征写入:
let data = String(0b1010).dataUsingEncoding(NSUTF8StringEncoding)!
peripheral.writeValue(ofCharacWithUUID: "1d5bc11d-e28c-4157-a7be-d8b742a013d8",
fromServiceWithUUID: "4011e369-5981-4dae-b686-619dc656c7ba",
value: data) { result in
switch result {
case .success:
break // The write was succesful.
case .failure(let error):
break // An error happened while writting the data.
}
}
接收特征更新通知
通过默认的NotificationCenter
上的通知接收特征值更新。所有支持的Peripheral
通知都是PeripheralEvent
枚举的一部分。注册通知时,请使用此枚举的原始值作为通知字符串。
// First we prepare ourselves to receive update notifications
let peripheral = somePeripheral
NotificationCenter.default.addObserver(forName: Peripheral.PeripheralCharacteristicValueUpdate,
object: peripheral,
queue: nil) { (notification) in
let charac = notification.userInfo!["characteristic"] as! CBCharacteristic
if let error = notification.userInfo?["error"] as? SBError {
// Deal with error
}
}
// We can then set a characteristic's notification value to true and start receiving updates to that characteristic
peripheral.setNotifyValue(toEnabled: true, forCharacWithUUID: "2A29", ofServiceWithUUID: "180A") { (isNotifying, error) in
// If there were no errors, you will now receive Notifications when that characteristic value gets updated.
}
发现服务
使用discoverServices(...)
函数发现服务
peripheral.discoverServices(withUUIDs: nil) { result in
switch result {
case .success(let services):
break // An array containing all the services requested
case .failure(let error):
break // A connection error or an array containing the UUIDs of the services that we're not found
}
}
与CBPeripheral的discoverServices(...)函数类似,传递nil而不是服务UUID数组将从该外围设备发现所有服务。
发现特征
使用discoverCharacteristics(...)
函数发现特征。如果您尝试从尚未发现的服务发现特征,将会先为您发现该服务。
peripheral.discoverCharacteristics(withUUIDs: nil, ofServiceWithUUID: "180A") { result in
// The characteristics discovered or an error if something went wrong.
switch result {
case .success(let services):
break // An array containing all the characs requested.
case .failure(let error):
break // A connection error or an array containing the UUIDs of the charac/services that we're not found.
}
}
与CBPeripheral的discoverCharacteristics(...)函数类似,传递nil而不是服务UUID数组将从该服务发现所有特征。
状态保存
SwiftyBluetooth由CBCentralManager单例包装支持,并且不会直接为您提供对底层CBCentralManager的直接访问。
但是,您仍然可以通过调用setSharedCentralInstanceWith(restoreIdentifier: )
来设置底层CBCentralManager以恢复状态,并可以使用您选择的恢复标识符。
请注意,此方法只能调用一次,并且必须在初始化库中的任何其他内容之前调用,否则第一次访问它时将触发Central sharedInstance的懒加载。
因此,建议在您的App Delegate的didFinishLaunchingWithOptions(:)
中调用它
SwiftyBluetooth.setSharedCentralInstanceWith(restoreIdentifier: "MY_APP_BLUETOOTH_STATE_RESTORE_IDENTIFIER")
在默认NotificationCenter上注册状态保存通知。这些通知将包含一个包含已恢复Peripheral
的数组。
NotificationCenter.default.addObserver(forName: Central.CentralManagerWillRestoreStateNotification,
object: Central.sharedInstance,
queue: nil) { (notification) in
if let restoredPeripherals = notification.userInfo?["peripherals"] as? [Peripheral] {
}
}
安装
CocoaPods
将其添加到您的Podfile中
pod 'SwiftyBluetooth', '~> 3.0.0'
Swift Package Manager
将库作为“包依赖项”简单地添加到您的xcode项目中
Carthage
将此添加到您的 Cartfile
github "jordanebelanger/SwiftyBluetooth"
需求
SwiftyBluetooth 需要 iOS 10.0 及以上版本
许可
SwiftyBluetooth 在 MIT 许可下发布。