在Swift3中的CBCharacteristic值

3

我是一名初学者,正在学习Swift开发。我正在开发一个基于BLE的应用程序。 今天我更新了Xcode 8和iOS 10,并将我的代码转换为Swift3。然后,我需要转换一些语法。在解决这个问题之后,我发现了一个关于CBCharacteristic的问题。

问题

在 didUpdateValueforCharacteristic 方法中,我可以获取更新后的CBCharacteristic对象。 如果我打印整个对象,它会正确显示 value = <3a02>。 但是当我从CBCharacteristic中检索值时,characteristic.value只显示2个字节(该值的大小)。

func peripheral(_ peripheral: CBPeripheral, didUpdateValueFor characteristic:     CBCharacteristic, error: Error?)
{
if (characteristic.uuid.description == LED_WAVELENGTH_CHARACTERISTIC_UUID)
{
            print("Characteristic - \(characteristic)")
            print("Data for characteristic  Wavelength - \  (characteristic.value)")
        }
 }

日志结果:

Characteristic - <CBCharacteristic: 0x1742a50a0, UUID = 2C14, properties = 0xE, value = <3a02>, notifying = NO>
Data for characteristic  Wavelength - Optional(2 bytes)

PS:这段代码在之前的版本中完全正常工作。

感谢关注,希望有人能帮助我解决这个问题。


是的,正确。我在我的问题中也提到了这一点。这是值的大小。在Swift 2.2中,返回结果为"<3a02>"。现在在Swift 3中,返回结果是值的大小。 - NyoSeint Lay
你没有得到2个字节。函数 characteristic.value.description() 返回了字符串“2 bytes”。当在Swift中的字符串上下文中评估对象(这是通过值内插在print语句中所做的)时,Swift实际上会调用对象的description函数并使用结果。在这种情况下,NSData(或在Swift 3中只是Data)包含2个字节,因此这就是“描述”该对象而不是它的值。3a02 确实是两个字节。它不是一个字节,也不是四个字节。 - Paulw11
我不明白你为什么对print语句的输出如此着迷。只需使用数据即可。 - Paulw11
我正在开发的应用程序是通过BLE与光度设备连接。根据光度设备,它们支持的波长是不同的。我需要使用此Characteristic UUID获取更新的波长。尽管我只显示了2个打印语句,但在我的实际代码中,从这个结果中还有很多工作要做。现在我无法获取任何特征数据值。无论如何,感谢您的关注。现在我正在使用swift 2.3进行测试。 - NyoSeint Lay
如果您在访问数据时遇到问题,请展示相关代码,说明出现了什么情况以及您期望的结果是什么。这里展示的代码按预期运行,因为它实际上并没有访问数据。 - Paulw11
显示剩余19条评论
2个回答

5

看起来你一直依赖于 NSDatadescription 方法返回形如 <xxxx> 的字符串来检索数据的值。这种方法很脆弱,正如你发现的那样,因为 description 方法只用于调试,且可能会在没有警告的情况下更改。

正确的方法是访问包装在 Data 对象中的字节数组。由于 Swift 2 允许将 UInt8 值复制到单个元素的 UInt16 数组中,因此这变得有点棘手。Swift 3 不再允许这样做,所以你需要自己计算。

var wavelength: UInt16?
if let data = characteristic.value {
    var bytes = Array(repeating: 0 as UInt8, count:someData.count/MemoryLayout<UInt8>.size)

    data.copyBytes(to: &bytes, count:data.count)
    let data16 = bytes.map { UInt16($0) }
    wavelength = 256 * data16[1] + data16[0]
}

print(wavelength) 

正确!!哇嗷..终于我能得到正确的结果了。非常感谢..现在我知道我的问题在哪里了。再次感谢。@Paulw11 - NyoSeint Lay

1
现在,您可以使用String(bytes: characteristic.value!, encoding: String.Encoding.utf8)来获取特征的字符串值。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接