NSString returns 空
NSString returns null
我在 Swift 中使用 CoreBluetooth 库,我想在 Characteristic 中读取我从外围设备接收到的内容。当我将特征值转换为 NSString 时,它总是 returns nil。你知道为什么吗 ?我认为是因为编码,因为我有一个可以读写的特性,当我向它写入内容时,我可以读取我写的内容。当我写 Characteristic 的值为 36 时,如果我写 6 并且此代码有效。如果我只想读取特征,则代码不起作用。
这是我的特征包含的内容
<CBCharacteristic: 0x1700a2a60, UUID = FFF2, properties = 0x2, value = <02>, notifying = NO>
这是代码
func peripheral(_ peripheral: CBPeripheral, didUpdateValueFor characteristic: CBCharacteristic, error: Error?) {
if error != nil {
print("Error on updating value on characteristic: \(characteristic) - \(String(describing: error?.localizedDescription))")
return
}
print(characteristic.value!)
print(NSString(data: characteristic.value!, encoding: String.Encoding.utf8.rawValue)!). //HERE IS NULL
guard let stringFromData = NSString(data: characteristic.value!, encoding: String.Encoding.utf8.rawValue) else
{
print("Invalid data")
return
}
//ALSO HERE stringFromData IS NULL
}
你应该按字节阅读它:
var out: UInt16 = 0
let formattedData = NSMutableData(length: yourBufferCapacity)!
(characteristic.value as NSData).getBytes(&out, range: NSRange(location: 0,length: MemoryLayout<UInt16>.size))
out = out.bigEndian //optional, check if you really need it
formattedData.replaceBytes(in: NSRange(location: 0,length: 2), withBytes: &out)
然后你可以将formattedData
转换为String
。
CBCharacteristic
的 value
属性 可能包含以其 uuid
定义的数千种格式编码的二进制数据。例如,它可以是大小为 8 位、16 位、32 位或 64 位的 signed/unsigned 个整数之一。或 7 字节日期和时间,或前面有长度的 UTF-16(LE) 字符串,或...并且可能包含它们的组合。
(一个复杂的例子,解码重量测量(UUID= 2A9D)。)
可能不是简单的字符串,所以NSString.init(data:encoding:)
(或者String.init(data:encoding:)
可能不行。
您需要为每个 uuid
获取 value
的字符串表示形式。
您可能需要这样写:
func peripheral(_ peripheral: CBPeripheral, didUpdateValueFor characteristic: CBCharacteristic, error: Error?) {
if error != nil {
print("Error on updating value on characteristic: \(characteristic) - \(error!.localizedDescription))")
return
}
guard let data = characteristic.value else {
print("characteristic.value is nil")
return
}
let uuidStr = characteristic.uuid.uuidString
let stringFromData: String
switch uuidStr {
case "FFF2":
//I do not know the UUID: FFF2, but seems you prefer it in hexadecimal
stringFromData = String(format: "%02X", data[0])
//Add other `case`s for other `uuid`s you want to show...
//case "XXXX":
// stringFromData = ...
//...
default:
stringFromData = "Unsupported UUID: \(uuidStr), data:\(data as NSData)"
}
print(stringFromData)
}
我在 Swift 中使用 CoreBluetooth 库,我想在 Characteristic 中读取我从外围设备接收到的内容。当我将特征值转换为 NSString 时,它总是 returns nil。你知道为什么吗 ?我认为是因为编码,因为我有一个可以读写的特性,当我向它写入内容时,我可以读取我写的内容。当我写 Characteristic 的值为 36 时,如果我写 6 并且此代码有效。如果我只想读取特征,则代码不起作用。
这是我的特征包含的内容
<CBCharacteristic: 0x1700a2a60, UUID = FFF2, properties = 0x2, value = <02>, notifying = NO>
这是代码
func peripheral(_ peripheral: CBPeripheral, didUpdateValueFor characteristic: CBCharacteristic, error: Error?) {
if error != nil {
print("Error on updating value on characteristic: \(characteristic) - \(String(describing: error?.localizedDescription))")
return
}
print(characteristic.value!)
print(NSString(data: characteristic.value!, encoding: String.Encoding.utf8.rawValue)!). //HERE IS NULL
guard let stringFromData = NSString(data: characteristic.value!, encoding: String.Encoding.utf8.rawValue) else
{
print("Invalid data")
return
}
//ALSO HERE stringFromData IS NULL
}
你应该按字节阅读它:
var out: UInt16 = 0
let formattedData = NSMutableData(length: yourBufferCapacity)!
(characteristic.value as NSData).getBytes(&out, range: NSRange(location: 0,length: MemoryLayout<UInt16>.size))
out = out.bigEndian //optional, check if you really need it
formattedData.replaceBytes(in: NSRange(location: 0,length: 2), withBytes: &out)
然后你可以将formattedData
转换为String
。
CBCharacteristic
的 value
属性 可能包含以其 uuid
定义的数千种格式编码的二进制数据。例如,它可以是大小为 8 位、16 位、32 位或 64 位的 signed/unsigned 个整数之一。或 7 字节日期和时间,或前面有长度的 UTF-16(LE) 字符串,或...并且可能包含它们的组合。
(一个复杂的例子,解码重量测量(UUID= 2A9D)
可能不是简单的字符串,所以NSString.init(data:encoding:)
(或者String.init(data:encoding:)
可能不行。
您需要为每个 uuid
获取 value
的字符串表示形式。
您可能需要这样写:
func peripheral(_ peripheral: CBPeripheral, didUpdateValueFor characteristic: CBCharacteristic, error: Error?) {
if error != nil {
print("Error on updating value on characteristic: \(characteristic) - \(error!.localizedDescription))")
return
}
guard let data = characteristic.value else {
print("characteristic.value is nil")
return
}
let uuidStr = characteristic.uuid.uuidString
let stringFromData: String
switch uuidStr {
case "FFF2":
//I do not know the UUID: FFF2, but seems you prefer it in hexadecimal
stringFromData = String(format: "%02X", data[0])
//Add other `case`s for other `uuid`s you want to show...
//case "XXXX":
// stringFromData = ...
//...
default:
stringFromData = "Unsupported UUID: \(uuidStr), data:\(data as NSData)"
}
print(stringFromData)
}