如何在Swift中从十六进制值创建NSData

3
我是一名初学Swift/iOS的新手,需要解决一个问题。我正在尝试从Texas Instrument SensorTag 2获取数据。根据说明书上的指导,为了激活一个传感器,我需要在我的传感器的配置库中写入二进制字符串。
这是我的代码片段:
        if SensorTag.validConfigCharacteristic(thisCharacteristic) {
            // Enable Sensor
            let enableByte = SensorTag.getEnableByteFor(thisCharacteristic)
            self.sensorTagPeripheral.writeValue(enableByte, forCharacteristic: thisCharacteristic, type: CBCharacteristicWriteType.WithResponse)
        }

我编写了一个函数来获取要写入的值。enableByte类型为NSData。

class func getEnableByteFor(thisCharacteristic: CBCharacteristic) -> NSData {
        print(thisCharacteristic.UUID)
        var enableValue = 0

        if thisCharacteristic.UUID == MovementConfigUUID {
            enableValue = ...
        } else { // any other activation
            enableValue = 1
        }

        return NSData(bytes: &enableValue, length: sizeof(UInt8))

    }

对于每个传感器,如果我想启用传感器,则必须写入1,如果要禁用传感器,则必须写入0。但是对于运动传感器,我必须根据此指南编写16位(2字节)。对于我的配置,我必须写入二进制值0000000001111111,即0x007F。如何使用值0x007F初始化NSData对象?

你所说的十六进制是指ASCII表示吗?因为这就是十六进制的含义,即可打印的表示。或者你只是想创建数据而没有中间的ASCII表示。另外,你需要的字节顺序是大端还是小端? - zaph
2个回答

1

试试这个:

let bytes : [CChar] = [0x0, 0x7F]
let data = NSData(bytes: bytes, length: 2)

NSData(bytes:length:) 从一个字节流创建一个 NSData 对象。在 Objective-C 中,这个字节流的类型是 char *Swift 等效[CChar]。问题(和另一个答案)使用 Int 来表示这个字节流。这是错误和危险的。

var enableValue = 0 // enableValue is a 64-bit integer
NSData(bytes: &enableValue, length: sizeof(UInt8)) // this trims it to the first 8 bits

这是因为x86使用小端编码,最不重要的字节排在最前面,所以它起作用。但在使用大端编码的PowerPC上会失败。ARM使用可切换字节序,因此可能会成功或失败。当需要精确的位布局时,不应该依赖于架构的字节顺序:

class func getEnableByteFor(thisCharacteristic: CBCharacteristic) -> NSData {
    print(thisCharacteristic.UUID)
    let enableValue : [CChar]

    if thisCharacteristic.UUID == MovementConfigUUID {
        enableValue = [0x0, 0x7F]
    } else { // any other activation
        enableValue = [0x1]
    }

    return NSData(bytes: enableValue, length: enableValue.count)
}

-1

考虑字节顺序的更短解决方案:

NSData(bytes: [UInt16(0x007F).bigEndian], length: 2)

现在使用[UInt16]作为字节流没有问题,因为UInt16有一个bigEndian属性,如果需要,返回整数的大端表示并更改字节顺序。

谢谢,现在我尝试着弄清楚如何重构我的代码以返回正确的NSData。 - Roberto Pezzali
1
@RobertoPezzali 如果我的回答有帮助,请考虑点赞和/或接受它。 - mixel
1
在需要精确的位布局时,请不要依赖于架构的字节序。 - Code Different
@ZoffDino 我更新了我的答案以符合该条件。 - mixel

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