Zach Zach - 3 months ago 18
iOS Question

How to detect endianess to keep a consistent byte order with iOS

I am having an issue with iOS byte orders. We are sending messages over BLE, some of the values are stored as NSInteger objects

I have an older (but still supported) iPad appears to store integers with big-endian byte order which is required for our peripheral to correctly interpret the value, however when I run the same application on a newer iPhone it doesn't work and the endianness is reversed.

NSInteger number = 230; /* this is actually declared elsewhere, this is just for the example */

short value = (short)number;

NSData* data = [NSData dataWithBytes:(void*)&value length:sizeof(value)];

int intData = [self intFromNSData:data];

NSLog(@"After conversion %d", intData);


The output is

On iPad: After conversion 230 (00E6)
On iPhone: After conversion 58880 (E600)


As you can see the byte order is different on the two devices, I just want to know how I can detect and, if necessary, swap the bytes before I send them to the peripheral device. Or is there a different way to store these numbers that will be consistent across all devices?

Answer

You don't need to detect the endianness of the device running your app. To ensure that you always send the bytes as big-endian, use the appropriate NSSwapHostXXXToBig function.

short value = 230;
short beValue = NSSwapHostShortToBig(value);
NSData *data = ...

Or you can use the CFSwapXXXHostToBig functions. These work well with the various fixed size data types such as uint16_t.

uint16_t value = 230;
uint16_t beValue = CGSwapInt16HostToBig(value);
NSData *data = ...

Each of these have corresponding functions to convert the big-endian value back to a proper host value if needed.