我正在使用Swift在Xcode上编写一个连接到蓝牙BLE外设的应用程序。我已建立与设备的连接,并希望从特定特征中读取一些数据(特别是服务UUID FFF0中的FFF1)。
如果我想查找信息的特征是characteristicx
,我可以使用以下代码请求读取特征:
peripheral.readValueForCharacteristic(charactericsx)
我想知道的是:我如何检查这个读取值是我正在寻找的。我希望能够执行if语句来检查我的值与该特征的已发现值。
例如:如果发现的值是X则执行某些操作,否则如果发现的值为Y则执行其他操作。
这不是我想要做的很好的解释,但我希望你能得到主旨。
任何人都知道如何做到这一点?
答案 0 :(得分:12)
针对Swift3进行了更新
执行该方法后,外围设备的delegate
将异步接收peripheral(_:didUpdateValueFor:error:)
方法。在该方法中,您可以查询传递的value
参数的characteristic
。 value
将是NSData
,您可以从中提取字节。 E.g。
// MARK: - CBPeripheralDelegate
func peripheral(_ peripheral: CBPeripheral, didUpdateValueFor characteristic: CBCharacteristic, error: Error?) {
if let e = error {
print("ERROR didUpdateValue \(e)")
return
}
guard let data = characteristic.value else { return }
...
}
value
方法实际上会在预期的Optional
周围返回Data
,因此可以采取放心行动。
通常,一个特征将具有一个简单的值,其编码在最高20字节Data
的有效载荷中。例如。也许这是一个简单的UInt16计数器。到
要在这些Data
限制和有意义的数字之间进行转换,请查看round trip Swift number types to/from Data的答案(我已经将我自己的实现包括在内)。
例如,如果你知道感兴趣的特征是一个意图被提取为UInt16
的计数器,我会用以下内容填写上面的例子:
// MARK: - CBPeripheralDelegate
func peripheral(_ peripheral: CBPeripheral, didUpdateValueFor characteristic: CBCharacteristic, error: Error?) {
if let e = error {
print("ERROR didUpdateValue \(e)")
return
}
guard let data = characteristic.value else { return }
print("counter is \(UInt16(data:data))")
}
// Data Extensions:
protocol DataConvertible {
init(data:Data)
var data:Data { get }
}
extension DataConvertible {
init(data:Data) {
guard data.count == MemoryLayout<Self>.size else {
fatalError("data size (\(data.count)) != type size (\(MemoryLayout<Self>.size))")
}
self = data.withUnsafeBytes { $0.pointee }
}
var data:Data {
var value = self
return Data(buffer: UnsafeBufferPointer(start: &value, count: 1))
}
}
extension UInt8:DataConvertible {}
extension UInt16:DataConvertible {}
extension UInt32:DataConvertible {}
extension Int32:DataConvertible {}
extension Int64:DataConvertible {}
extension Double:DataConvertible {}
extension Float:DataConvertible {}