trying to convert NSData of type (BigEndian) from BlueTooth to Int of type Little Endian in Swift

1.6k views Asked by At

I am trying to convert a 6 byte hex of type NSData i got via bluetooth connection to appropriate integer values. I know this is of type Big Endian and i need to covnert to little Endian. However, every time i try to convert it, i can extract the right data, but the results look wrong, see playground code below:

var newdata = NSData(bytes: [0x26, 0x01, 0x45, 0x01, 0x04, 0x5e, ] as [UInt8], length:6)


//var timeData  = newdata.subdataWithRange(NSMakeRange(4,2))
//var heelData = newdata.subdataWithRange(NSMakeRange(2,2))
//var frontData = newdata.subdataWithRange(NSMakeRange(0,2))


var timeData:UInt16 = 0 
var heelData:UInt16 = 0
var frontData:UInt16 = 0


//var timeData = data.subdataWithRange(NSMakeRange(4,2))

var timeIn: NSNumber = NSNumber(unsignedShort: 0)
newdata.getBytes(&timeIn, range: NSRange(location: 4,length: 2))
timeData = CFSwapInt16BigToHost(timeIn.unsignedShortValue)
//24068

 var heelIn: NSNumber = NSNumber(unsignedShort: 0)
 newdata.getBytes(&heelIn, range: NSRange(location: 2, length: 2))
 heelData = CFSwapInt16BigToHost(heelIn.unsignedShortValue)
 //325

 var frontIn: NSNumber = NSNumber(unsignedShort: 0)
 newdata.getBytes(&frontIn, range: NSRange(location: 0, length: 2))
 frontData = CFSwapInt16BigToHost(frontIn.unsignedShortValue)
 //294
1

There are 1 answers

0
Martin R On

NSNumber is a Foundation class and in particular a value type, and timeIn is a pointer to a number instance. You are extracting the bytes into that pointer, which is not what you want and can cause all kinds of undefined behavior or crashes.

What you should do is to extract the bytes into an UInt16 variable:

var timeData:UInt16 = 0 
newdata.getBytes(&timeData, range: NSRange(location: 4, length: 2))
timeData = CFSwapInt16BigToHost(timeData)
// Result: 1118 = 0x045E

An alternative to the last conversion is

/// Creates an integer from its big-endian representation, changing the
/// byte order if necessary.
timeData = UInt16(bigEndian: timeData)