I'm new in the area of Objective-C.
My question is, how can I Send a byte format like b70f using NSData?
So, basically I have to make a variable first with the value of b70f and then write it to the peripheral.
[peripheral writeValue:[NSData dataWithBytes:&value length:1] forCharacteristic:characteristic type:CBCharacteristicWriteWithResponse];
How can I do this?
Any help would be appreciated.
Assuming that b70f is a 16-bit value, something like this should work...
uint16_t value = 0xb70f;
NSData *data = [NSData dataWithBytes:&value length:2];
This takes advantage that an "array" of two bytes fits into a single 16-bit integer.
If the bytes are in the wrong order, wrap the assignment with OSSwapInt16().
uint16_t value = OSSwapInt16(0xb70f);
Related
I have some NSData instance with 2 bytes of different value.
Will calling getBytes: of any kind (length, range...) also advance the current position in the buffer?
Example:
NSData *data = ...; // 2 bytes data
[data getBytes:&whatever1 length:1]; // reading first byte
[data getBytes:&whatever2 length:1]; // reading first OR second byte?
Will the contents that I get on each time getBytes:length: is called be the same first byte in the NSData instance or will the first call advance the next call to read from the second byte?
Thanks!
No, it does not.
In the example it will access the same byte (first).
To access the "next" byte you'll need to use getBytes:range: but, like #hot-licks commented, NSData is immutable and therefore won't be modified.
I have an NSData packet with data in it. I need to convert the byte at range 8, 1 to an int. To get the data at that location I do the following.
NSData *byte = [packet subdataWithRange:NSMakeRange(8, 1)];
If I NSLog byte
<01>
How do I think convert this to an int? This is probably the most basic of questions but I am just not getting it right.
Any help would be appreciated.
Update
With that data the int should be equal to 1. I am not sure if this has anything todo with Endian.
use -[NSData bytes] to get raw buffer and read from it
int i = *((char *)[byte bytes])
or use -[NSData getBytes:length:]
char buff;
[bytes getBytes:&buff length:1];
int i = buff;
make sure you are reading from char * not int *, otherwise you are accessing invalid memory location, which may or may not crash or provide correct result.
I am trying to get a float value from a NSData object which contains several hex values. e.g. EC 51 38 41
From this 4 Byte values i want to get the float value 11.52. How do i have to do this in xcode?
I have tried it with NSScanner (scanFloat, scanHexFloat), NSNumberformatter and NSNumber, i created an Byte Array and tried float myFloat = *(float*)&myByteArray. All these Options i found here at stackoverflow.
I tested it in Windows with C# and there it was no problem:
byte[] bytes = new byte[4] { 0xEC, 0x51, 0x38, 0x41 };
float myFloat = System.BitConverter.ToSingle(bytes, 0);
Does anybody know how i have to do this in xcode???
Thanks, Benjamin
When converting binary data from a foreign protocol always make sure to include proper swapping for endianness:
uint32_t hostData = CFSwapInt32BigToHost(*(const uint32_t *)[data bytes]);
float value = *(float *)(&hostData);
You have to know the endianness of the encoded data. You might need to use CFSwapInt32LittleToHost instead.
NSData * data = ...; // loaded from bluetooth
float z;
[data getBytes:&z length:sizeof(float)];
Try this.
I have tries it with NSScanner (scanFloat, scanHexFloat), NSNumberformatter and NSNumber
You're barking up the wrong tree here. NSScanner is for scanning strings. NSNumber is not the same as NSData, and NSNumberFormatter won't work with NSData either.
NSData is a container for plain old binary data. You've apparently got a float stored in an NSData instance; if you want to access it, you'll need to get the data's bytes and then interpret those bytes however you like, e.g. by casting to float:
float *p = (float*)[myData bytes]; // -bytes returns a void* that points to the data
float f = *p;
I'm trying to send hexadecimal data via WiFi.
The code is something like this:
NSString *abc = #"0x1b 0x50";
NSData *data = [[[NSData alloc] initWithData:[abc dataUsingEncoding:NSASCIIStringEncoding]]autorelease];
[outputStream write:[data bytes] maxLength:[data length]]];
Instead of sending the hexadecimal data, it's sending it in text format.
I tried with NSUTF8StringEncoding, but it's the same. I'm using it with the NSStream class.
You're not getting what you expect with NSString *abc = #"0x1b 0x50". It's almost the same as having NSString *abc = #"cat dog 123 0x0x0x"; just a bunch of words separated by spaces. So when you create your NSData object, you're just initializing it with a string of characters, not a series of actual numbers.
If you can get your numbers into an NSArray, this question/answer should help you: How to convert NSArray to NSData?
The data that you probably want to send is simply 0x1b50, which is the decimal number 6992 (assuming big-endian), and fits into two bytes. This is not the same as a string (which could contain anything) even if it happens to contain some human-readable representation of those numbers.
I'm assuming you want to send this as binary data, and if so one way would be to simply send a buffer formed by a single UInt16 instead of a string. I'm not very familiar with the relevant APIs, but look to see if you can populate the NSData with an integer, perhaps something like:
UInt16 i = 0x1b50; // Or = 6992
[[NSData alloc] initWithBytes: &i length: sizeof(i)]
[outputStream write: [data bytes] maxLength: [data length]]];
Again, I'm not fluent with Objective C, but this should be the general approach to sending the number 0x1b50 as binary data.
How do you append a NSInteger to NSMutableData. Something allong the lines of...
NSMutableData *myData = [[NSMutableData alloc] init];
NSInteger myInteger = 42;
[myData appendBytes:myInteger length:sizeof(myInteger)];
So that 0x0000002A will get appended to myData.
Any help appreciated.
Pass the address of the integer, not the integer itself. appendBytes:length: expects a pointer to a data buffer and the size of the data buffer. In this case, the "data buffer" is the integer.
[myData appendBytes:&myInteger length:sizeof(myInteger)];
Keep in mind, though, that this will use your computer's endianness to encode it. If you plan on writing the data to a file or sending it across the network, you should use a known endianness instead. For example, to convert from host (your machine) to network endianness, use htonl():
uint32_t theInt = htonl((uint32_t)myInteger);
[myData appendBytes:&theInt length:sizeof(theInt)];