NSString 返回空

Posted

技术标签:

【中文标题】NSString 返回空【英文标题】:NSString returns null 【发布时间】:2017-07-24 10:18:48 【问题描述】:

我在 Swift 中使用 CoreBluetooth 库,我想阅读我从 Characteristic 中的外围设备接收到的内容。当我将特征的值转换为 NSString 时,它总是返回 nil。你知道为什么吗 ?我认为是因为编码,因为我有一个可以读写的特性,当我向它写东西时,我可以阅读我写的东西。当我写的时候,如果我写 6,那么 Characteristic 的值为 36,并且这段代码有效。如果我只想读取一个特征,则代码不起作用。

这就是我的特征所包含的

<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


【问题讨论】:

这里是 print(characteristic.value!) ? 它显示 1 个字节 您可以尝试 ascii 编码,但如果您的数据是通过外围设备的“虚拟串行端口”发送的,您可能需要收集多个数据包来获取您的字符串 这应该是什么价值?可以改为 Int 吗? 【参考方案1】:

CBCharacteristicvalue 属性可能包含用其uuid 定义的数千种格式编码的二进制数据。例如,它可以是大小为 8 位、16 位、32 位或 64 位的有符号/无符号整数之一。或者 7 字节的日期和时间,或者以长度为前缀的 UTF-16(LE) 字符串,或者... 并且可能包含它们的组合。

(一个复杂的例子,解码Weight Measurement (UUID= 2A9D) here。)

它可能不是一个简单的字符串,所以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)

【讨论】:

谢谢。我用了你的答案【参考方案2】:

你应该按字节读取它:

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

【讨论】:

以上是关于NSString 返回空的主要内容,如果未能解决你的问题,请参考以下文章

核心数据:分组和计数结果返回空列表

将 NSData 转换为 NSString 的空结果

在另一个文件中使用 NSString 对象总是显示空值?

JSON:NSString stringWithContentsOfURL ...流中有null,崩溃

使用 reverseGeocodeLocation 将用户的状态作为 NSString 返回

将 NSData 转换为 NSString 返回 nil