Reading received packets in didUpdateValueForCharacteristic - ios

I need to read the received bytes and parse them with a custom method, which basically goes through bytes and skips every 0x7D (or a } ). But what happens now is that it does that for only one received packet, and I dont know why that is happening since im calling my method in didUpdateValueForCharacteristic :
- (void) peripheral:(CBPeripheral *)peripheral didUpdateValueForCharacteristic:(CBCharacteristic *)characteristic error:(NSError *)error
{
if (error)
{
NSLog(#"Error receiving notification for characteristic %#: %#", characteristic, error);
return;
}
NSLog(#"Received data on a characteristic.");
if (characteristic == self.rxCharacteristic)
{
self.bluetoothData = [[NSMutableData alloc] initWithData:[characteristic value]];
[self unstuff1:[characteristic value]];
NSLog(#"First NSDAta %#", self.bluetoothData);
[self unstuff1:self.bluetoothData];
NSLog(#"Parsed First NSDATA %#", self.bluetoothData);
NSString *stringForPrintingOutToConsole = [[NSString alloc] initWithData:self.bluetoothData encoding:NSASCIIStringEncoding];
[self.delegate didReceiveData:stringForPrintingOutToConsole];
}
else if ([characteristic.UUID isEqual:self.class.hardwareRevisionStringUUID])
{
NSString *hwRevision = #"";
const uint8_t *bytes = characteristic.value.bytes;
for (int i = 0; i < characteristic.value.length; i++)
{
NSLog(#"%x", bytes[i]);
hwRevision = [hwRevision stringByAppendingFormat:#"0x%02x, ", bytes[i]];
}
// this one reads the hardware revision
[self.delegate didReadHardwareRevisionString:[hwRevision substringToIndex:hwRevision.length-2]];
}
}
and a custom method for parsing :
- (NSMutableData *)unstuff1:(NSMutableData *)mutableData {
NSUInteger dataLength = [self.bluetoothData length];
unsigned char *bytes = [self.bluetoothData bytes];
uint16_t i, j = 0;
for (int i = 0; i < dataLength; i++)
{
if (bytes[i] == 0x7D)
{
bytes[j] = bytes[i+1] ^ 0x20;
i++;
} else
{
bytes[j] = bytes[i];
j++;
}
}
return mutableData;
}
if anyone has a clue, i'd highly appreciate help.

Related

iOS reading data from bluetooth 4.2 BLE device

I'm trying to read data from a BLE device getting the data from delegate method
- (void)peripheral:(CBPeripheral *)peripheral didUpdateValueForCharacteristic:(CBCharacteristic *)characteristic error:(NSError *)error.
I am reading the data from CBCharacteristic object by using property value.
This returns the NSData.
I converted this NSData to Bytes.
How to Calculate the Weight from this Bytes data?. By this code i am not getting exact value.
Here is MyCode
/** This callback lets us know more data has arrived via notification on the characteristic
*/
- (void)peripheral:(CBPeripheral *)peripheral didUpdateValueForCharacteristic:(CBCharacteristic *)characteristic error:(NSError *)error
{
NSLog(#"peripheral %#", peripheral);
NSLog(#"chacteristic %#", characteristic);
NSLog(#"chacteristic value %#", [characteristic value]);
Response Is Like This
peripheral <CBPeripheral: 0x15e469e90, identifier = A4B7E3A0-A988-02CF-3FAE-3B62056F465B, name = eBody-Fat-Scale, state = connected>
chacteristic <CBCharacteristic: 0x15e250980, UUID = 2A9D, properties = 0x20, value = <0ee803df 07010116 390901ff ff0000>, notifying = YES>
chacteristic value <0ee803df 07010116 390901ff ff0000>
if (error) {
NSLog(#"Error discovering characteristics: %# and %#", [error localizedDescription],[error localizedFailureReason]);
return;
}
int height;
self.targetPeripheral = peripheral;
NSData *tempData=characteristic.value;
NSString *stringFromData = [[NSString alloc] initWithData:characteristic.value encoding:NSUTF8StringEncoding];
NSString *str = [NSString stringWithUTF8String:[tempData bytes]];
NSLog(#"string data %#",str);
NSData *lol = characteristic.value;
NSLog(#"length %lu", (unsigned long)[lol length]);
Byte *byte = (Byte *)[lol bytes];
for(int i = 0;i<[lol length];i++)
{
NSLog(#"Receive byte:%d",byte[i]);
}
/* self.targetPeripheral = peripheral;
NSString *stringFromData = [[NSString alloc] initWithData:characteristic.value encoding:NSUTF8StringEncoding];
NSData *lol = characteristic.value;
Byte *byte = (Byte *)[lol bytes];
for(int i = 0;i<[lol length];i++)
{
NSLog(#"Received bytes:%d",byte[i]);
}*/
if(byte[0] == 0xfc)
{
Byte weightHigh = 0;
if(byte[1] >= 0xc0)
{
weightHigh = byte[1] - 0xc0;
}
else if(byte[1] >= 0x80)
{
weightHigh = byte[1] - 0x80;
}
else if(byte[1]>= 0x40)
{
weightHigh = byte[1] - 0x40;
}
float weightdata = (float)(weightHigh * 256 + byte[2])/10;
NSUserDefaults *prefers = [NSUserDefaults standardUserDefaults];
if([[prefers objectForKey:#"units"] isEqualToString:#"ft"])
{
NSString *weight = [[NSString alloc]initWithFormat:#"%.1f",[UnitParse convertKgToLb:weightdata]];
_weightDataLabel.text = [[NSString alloc] initWithFormat:#"%#",weight];
}
else
{
NSString *weight = [[NSString alloc]initWithFormat:#"%.1f",weightdata];
_weightDataLabel.text = [[NSString alloc] initWithFormat:#"%#",weight];
}
if(weightdata != _lastWeightData)
{
[RCCircleAnimation stopAnimation:_circleImageView.layer];
_lastWeightData = weightdata;
if(weightHigh * 256 + byte[2] == 0x3f*256+255)//overload
{
_weightDataLabel.text = #"overload";
}
else
{
NSThread* myThread1 = [[NSThread alloc] initWithTarget:self selector:#selector(mySoundPlayer)object:nil];
[myThread1 start];
NSMutableDictionary *dic = [[NSMutableDictionary alloc]init];
[dic setObject:[[NSString alloc] initWithFormat:#"%2f",weightdata] forKey:#"Weight"];
NSDateFormatter *formatter = [[NSDateFormatter alloc]init];
[formatter setDateFormat:#"yyyy-MM-dd HH:mm:ss"];
NSString *datestr = [formatter stringFromDate:[NSDate date]];
[dic setObject:datestr forKey:#"TestTime"];
/* // First Time
NSUserDefaults *userDefaults ;
userDefaults = [NSUserDefaults standardUserDefaults];
if ([userDefaults objectForKey:#"UserWeightDataArray"] == nil)
{
[_valuesArray addObject:dic];
[userDefaults setObject:_valuesArray forKey:#"UserWeightDataArray"];
[userDefaults synchronize];
}
else
{
// second Time
[_dateArray addObject:dic];
_finalArray = [[_dateArray arrayByAddingObjectsFromArray:[[NSUserDefaults standardUserDefaults] objectForKey:#"UserWeightDataArray"]] mutableCopy];
[userDefaults setObject:_finalArray forKey:#"UserWeightDataArray"];
[userDefaults synchronize];
}
*/
height = [[[MySingleton sharedSingleton].nowuserinfo valueForKey:#"Height"] intValue];
float bmi = weightdata/((height/100.0f)*(height/100.0f));
_bmiDataLabel.text = [[NSString alloc] initWithFormat:#"%.1f",bmi];
NSLog(#"_weightDataLabel.text %#", _weightDataLabel.text);
[self uploadDeviceInformationToServer:height weight:[[NSString alloc]initWithFormat:#"%.1f",weightdata]];
NSThread* myThread2 = [[NSThread alloc] initWithTarget:self selector:#selector(uploadWeightData:)object:dic];
[myThread2 start];
NSThread* myThread3 = [[NSThread alloc] initWithTarget:self selector:#selector(getAdviceByWeightData:)object:dic];
[myThread3 start];
NSThread* myThread = [[NSThread alloc] initWithTarget:self selector:#selector(sendCloseCmd)object:nil];
[myThread start];
}
}
}
else
{
_lastWeightData = 0;
Byte weightHigh = 0;
if(byte[1] >= 0xc0)
{
weightHigh = byte[1] - 0xc0;
}
else if(byte[1] >= 0x80)
{
weightHigh = byte[1] - 0x80;
}
else if(byte[1]>= 0x40)
{
weightHigh = byte[1] - 0x40;
}
float weightdata = (float)(weightHigh * 256 + byte[2])/10;
NSUserDefaults *prefers = [NSUserDefaults standardUserDefaults];
NSLog(#"data is %#",[prefers objectForKey:#"units"]);
if([[prefers objectForKey:#"units"] isEqualToString:#"ft"])
{
double temp=[UnitParse convertKgToLb:weightdata];
double temp1=[UnitParse convertLbToKg:weightdata];
NSString *weight = [[NSString alloc]initWithFormat:#"%.1f",temp];
NSLog(#"weight in if .... %# and lb is %.1f and kg %.1f",weight,temp,temp1);
_weightDataLabel.text = [[NSString alloc] initWithFormat:#"%#",weight];
}
else
{
double temp=[UnitParse convertKgToLb:weightdata];
double temp1=[UnitParse convertLbToKg:weightdata];
NSLog(#"weight in if .... %f and lb is %.1f and kg %.1f",weightdata,temp,temp1);
NSString *weight = [[NSString alloc]initWithFormat:#"%.1f",temp1];
NSLog(#"weight in else .... %#",weight);
_weightDataLabel.text = [[NSString alloc] initWithFormat:#"%#",weight];
}
// NSString *weight = [[NSString alloc]initWithFormat:#"%.1f",[UnitParse convertKgToLb:weightdata]];
// _weightDataLabel.text = [[NSString alloc] initWithFormat:#"%#",weight];
}
// Have we got everything we need?
if ([stringFromData isEqualToString:#"EOM"]) {
// We have, so show the data,
//[self.textview setText:[[NSString alloc] initWithData:self.data encoding:NSUTF8StringEncoding]];
NSLog(#"GetDataValue : %#",[[NSString alloc] initWithData:self.data encoding:NSUTF8StringEncoding]);
// Cancel our subscription to the characteristic
[peripheral setNotifyValue:NO forCharacteristic:characteristic];
// and disconnect from the peripehral
[self.centralManager cancelPeripheralConnection:peripheral];
}
}
output of bytes data is:
Receive byte:14 byte data is 0xe
Receive byte:176 byte data is 0xb0
Receive byte:4 byte data is 0x4
Receive byte:223 byte data is 0xdf
Receive byte:7 byte data is 0x7
Receive byte:1 byte data is 0x1
Receive byte:1 byte data is 0x1
Receive byte:23 byte data is 0x17
Receive byte:48 byte data is 0x30
Receive byte:17 byte data is 0x11
Receive byte:1 byte data is 0x1
Use this code for read the byte data of weight or heart rate or temperature.
Lol is the nsdata object.
const uint8_t *reportData = [lol bytes];
uint16_t bpm = (uint16_t)reportData;
CGFloat weightdata = 0;
if ((reportData[1] & 0x01) == 0)
{
/* uint8 bpm */
NSLog(#"if reportData is %d",reportData[1]);
bpm = CFSwapInt16LittleToHost(*(uint16_t *)(&reportData[1]));
NSLog(#"if bpm data is %d",bpm);
weightdata = bpm/200.0;
}
else
{
/* uint16 bpm */
NSLog(#"reportData is %d",reportData[1]);
bpm = CFSwapInt16LittleToHost(*(uint16_t *)(&reportData[1]));
NSLog(#"bpm data is %d",bpm);
weightdata = bpm/200.0;
}

Reading large files from NSInputstream is not working in ios

I am trying to read large Image file more than 300KB from NSInputStream. But i'm getting only upto 300KB. Other data are missing. Could you please help me if you know. i'm waiting for your valuable answer.
I mentioned my code below :
Call this readAllData method from NSStreamEventsHasBytesAvailable:
- (void)readAllData {
if (_readData == nil) {
_readData = [[NSMutableData data] retain];
}
while ([[_session inputStream] hasBytesAvailable])
{
unsigned int bytesRead = 0;
bytesRead = [[_session inputStream] read:buf maxLength:EAD_INPUT_BUFFER_SIZE];
if (bytesRead) {
NSMutableString *_string = [NSMutableString stringWithString:#""];
for (int i = 0; i < _readData.length; i++) {
unsigned char _byte;
[_readData getBytes:&_byte range:NSMakeRange(i, 1)];
if (_byte >= 32 && _byte < 127) {
[_string appendFormat:#"%c", _byte];
} else {
[_string appendFormat:#"[%d]", _byte];
}
}
[_readData appendBytes:(const void *)buf length:bytesRead];
}
}
NSString *string=[NSString stringWithFormat:#"%d",_readData.length];
UIAlertView *sesView = [[UIAlertView alloc] initWithTitle:#"readDatalength"
message:string
delegate:self
cancelButtonTitle:nil otherButtonTitles:#"OK" , nil];
[sesView show];
}
When method hasBytesAvailable returns NO it doesn't always mean, that NSInputStream is empty. NSInputStream is at end only when its status is NSStreamStatusAtEnd. For example a stream which was been built from NSURL is asynchronous and it has no all bytes immediately after opening. If that is your case you should subscribe to NSInputStream declaring some class as NSStreamDelegate.

Interpret bytes received from bluetooth weight scale device in iOS

I am integrating a weight scale device in our iOS Application. The Device name nutriscale weight scale. I am using apple provided API -CBCentralManager for connecting and getting data from weight scale. I am able to detect services and characteristics of bluetooth device and getting some data from weight scale device after connecting but not able to interpret that data. I am able to get weight if it's below 255 gram. If it goes beyond 255. it gives me weight-255 answer.
Kindly correct me for this.
Here it's my code:
When i call [aPeripheral readValueForCharacteristic:aChar]; A delegate method below is being called.
- (void) peripheral:(CBPeripheral *)aPeripheral didUpdateValueForCharacteristic:(CBCharacteristic *)characteristic error:(NSError *)error {// NSLog(#"Descriptor %#",[characteristic properties]);if ([characteristic.UUID isEqual:[CBUUID UUIDWithString:HELLOBLUETOOTH_CHARACTERISTICS_NAME_UUID]])
{
pName = [[NSString alloc] initWithUTF8String:[[characteristic value]bytes]];
NSError *errorVa;
NSLog(#"KeyfobViewController didUpdateValueForCharacteristic %#", characteristic);
[aPeripheral setNotifyValue:YES forCharacteristic:characteristic];
[self getWeightData:characteristic error:errorVa];
}}
To interpret bytes i wrote this method
(void) getWeightData:(CBCharacteristic *)characteristic error:(NSError *)error{
// Get the Heart Rate Monitor BPM
NSData *data = [characteristic value];// 1
const uint8_t *reportData = [data bytes];
const uint16_t *reportData1 = [data bytes];
uint16_t weightValue = 0;
uint16_t weightValue1 = 0;
if(reportData)
{
if ((reportData[0] & 0x01) == 0) { // 2
// Retrieve the weight from the scale
weightValue = reportData[1];
int result= CFSwapInt16LittleToHost(*(uint16_t *)(&reportData[1]));
}
else
{
weightValue = CFSwapInt32LittleToHost(*(uint32_t *)(&reportData[1])); // 3
int result= CFSwapInt32LittleToHost(*(uint32_t *)(&reportData[1]));
NSLog(#"weightValue1 - %hhu",weightValue);
}
NSMutableArray *arrr = [NSMutableArray new];
uint8_t byte1 = reportData[0];
for (int i = 0; i < 8; i++) {int mask = 1 << i;if ((byte1 & mask) == 0) {[arrr addObject:#"0"];} else {[arrr addObject:#"1"];}}
NSLog(#"values1 - %#%#%#%#%#%#%#%#",arrr[7],arrr[6],arrr[5],arrr[4],arrr[3],arrr[2],arrr[1],arrr[0]);
[arrr removeAllObjects];
for (int i = 0; i < 16; i++) {int mask = 1 << i;if ((weightValue1 & mask) == 0) {[arrr addObject:#"0"];} else {[arrr addObject:#"1"];}}
NSLog(#"values2 - %#%#%#%#%#%#%#%#%#%#%#%#%#%#%#%#",arrr[15],arrr[14],arrr[13],arrr[12],arrr[11],arrr[10],arrr[9],arrr[8],arrr[7],arrr[6],arrr[5],arrr[4],arrr[3],arrr[2],arrr[1],arrr[0]);
// NSLog(#"values0 - %#%#%#%#%#%#%#%#",arrr[0],arrr[1],arrr[2],arrr[3],arrr[4],arrr[5],arrr[6],arrr[7]);
// NSLog(#"values2 - %#%#%#%#%#%#%#%#%#%#%#%#%#%#%#%#",arrr[0],arrr[1],arrr[2],arrr[3],arrr[4],arrr[5],arrr[6],arrr[7],arrr[8],arrr[9],arrr[10],arrr[11],arrr[12],arrr[13],arrr[14],arrr[15]);
}
// Display the weight value to the UI if no error occurred
if( (characteristic.value) || !error )
{ //
NSString *weight = [NSString stringWithFormat:#"%i", weightValue];
if([weight floatValue])
{
NSUserDefaults *defaultObject = [NSUserDefaults standardUserDefaults];
[defaultObject setObject:data forKey:#"data"];
[defaultObject synchronize];
NSString *strWeight=#"";
strWeight = [NSString stringWithFormat:#"%#",weight];
strWeight = [NSString stringWithFormat:#"%.1f",[strWeight floatValue]*0.035274];//
//[self bluetoothResponseToClass];
}
}
return;}
Kindly help me in this code. What am i doing wrong ?
Replace your function with below function
-(void) getWeightData:(CBCharacteristic *)characteristic error:(NSError *)error
{
// Get the Heart Rate Monitor BPM
NSData *data = [characteristic value];// 1
const uint8_t *reportData = [data bytes];
uint16_t weightValue = 0;
uint16_t chkValue = 0;
if(reportData)
{
chkValue = reportData[0];
weightValue = CFSwapInt32LittleToHost(*(uint32_t *)(&reportData[1]));
int var = (chkValue % 160);
weightValue = weightValue + var * 256;
NSMutableArray *arrr = [NSMutableArray new];
uint8_t byte1 = reportData[0];
for (int i = 0; i < 8; i++) {int mask = 1 << i;if ((byte1 & mask) == 0) {[arrr addObject:#"0"];} else {[arrr addObject:#"1"];}}
NSLog(#"values1 - %#%#%#%#%#%#%#%#",arrr[7],arrr[6],arrr[5],arrr[4],arrr[3],arrr[2],arrr[1],arrr[0]);
[arrr removeAllObjects];
for (int i = 0; i < 16; i++) {int mask = 1 << i;if ((chkValue & mask) == 0) {[arrr addObject:#"0"];} else {[arrr addObject:#"1"];}}
NSLog(#"values2 - %#%#%#%#%#%#%#%#%#%#%#%#%#%#%#%#",arrr[15],arrr[14],arrr[13],arrr[12],arrr[11],arrr[10],arrr[9],arrr[8],arrr[7],arrr[6],arrr[5],arrr[4],arrr[3],arrr[2],arrr[1],arrr[0]);
}
// Display the weight value to the UI if no error occurred
if( (characteristic.value) || !error )
{ //
NSString *weight = [NSString stringWithFormat:#"%i", weightValue];
lbl_Weight.text = [NSString stringWithFormat:#"%hu", weightValue];
if([weight floatValue])
{
NSUserDefaults *defaultObject = [NSUserDefaults standardUserDefaults];
[defaultObject setObject:data forKey:#"data"];
[defaultObject synchronize];
NSString *strWeight=#"";
strWeight = [NSString stringWithFormat:#"%#",weight];
strWeight = [NSString stringWithFormat:#"%.1f",[strWeight floatValue]*0.035274];//
//[self bluetoothResponseToClass];
}
}
return;
}

Storing and Retrieving compressed texts as BLOB from Sqlite via FMDB

I am trying to store text data as compressed blobs.
[db executeUpdate:#"create table blobTable (a text, b blob)"];
[db executeUpdate:#"insert into blobTable (a, b) values (?, compressMe('random text string'))", #"lord of the rings"];
And then I try to query them using:
FMResultSet *rs = [db executeQuery:#"select uncompressMe(b) as k from blobTable where a = ?", #"lord of the rings"];
Where compressMe and uncompressMe are defined as:
FMDatabaseQueue *queue = [FMDatabaseQueue databaseQueueWithPath:dbPath];
[queue inDatabase:^(FMDatabase *adb) {
[adb makeFunctionNamed:#"compressMe" maximumArguments:1 withBlock:^(sqlite3_context *context, int aargc, sqlite3_value **aargv) {
if (sqlite3_value_type(aargv[0]) == SQLITE_TEXT) {
#autoreleasepool {
const char *c = (const char *)sqlite3_value_text(aargv[0]);
NSString *s = [NSString stringWithUTF8String:c];
NSLog(#"string to compress: %#", s);
NSData *compressedBody = [self gzipDeflate:[s dataUsingEncoding:NSUTF8StringEncoding]];
sqlite3_result_blob(context, (__bridge const void *)(compressedBody), [compressedBody length], nil);
}
}
else {
NSLog(#"Unknown formart for StringStartsWithH (%d) %s:%d", sqlite3_value_type(aargv[0]), __FUNCTION__, __LINE__);
sqlite3_result_null(context);
}
}];
}];
[queue inDatabase:^(FMDatabase *adb) {
[adb makeFunctionNamed:#"uncompressMe" maximumArguments:1 withBlock:^(sqlite3_context *context, int aargc, sqlite3_value **aargv) {
if (sqlite3_value_type(aargv[0]) == SQLITE_BLOB) {
#autoreleasepool {
NSLog(#"inside uncompressMe");
NSUInteger len = sqlite3_value_bytes(aargv[0]);
Byte *byteData = (Byte*)malloc(len);
memcpy(byteData, sqlite3_value_blob(aargv[0]), len);
NSData *data = [[NSData alloc] initWithBytes:byteData length:len];
NSData *deflatedBody = [self gzipInflate:data];
NSString *deflatedString = [[NSString alloc] initWithData:deflatedBody encoding:NSUTF8StringEncoding];
sqlite3_result_text(context, (__bridge const void *)(deflatedString), -1, SQLITE_UTF8);
}
}
else {
NSLog(#"Unknown formart for StringStartsWithH (%d) %s:%d", sqlite3_value_type(aargv[0]), __FUNCTION__, __LINE__);
sqlite3_result_null(context);
}
}];
}];
For the sake of completeness, the zip functions are defined as such:
- (NSData *)gzipInflate:(NSData*)data
{
if ([data length] == 0) return data;
unsigned full_length = [data length];
unsigned half_length = [data length] / 2;
NSMutableData *decompressed = [NSMutableData dataWithLength: full_length + half_length];
BOOL done = NO;
int status;
z_stream strm;
strm.next_in = (Bytef *)[data bytes];
strm.avail_in = [data length];
strm.total_out = 0;
strm.zalloc = Z_NULL;
strm.zfree = Z_NULL;
if (inflateInit2(&strm, (15+32)) != Z_OK) return nil;
while (!done)
{
// Make sure we have enough room and reset the lengths.
if (strm.total_out >= [decompressed length])
[decompressed increaseLengthBy: half_length];
strm.next_out = [decompressed mutableBytes] + strm.total_out;
strm.avail_out = [decompressed length] - strm.total_out;
// Inflate another chunk.
status = inflate (&strm, Z_SYNC_FLUSH);
if (status == Z_STREAM_END) done = YES;
else if (status != Z_OK) break;
}
if (inflateEnd (&strm) != Z_OK) return nil;
// Set real length.
if (done)
{
[decompressed setLength: strm.total_out];
return [NSData dataWithData: decompressed];
}
else return nil;
}
- (NSData *)gzipDeflate:(NSData*)data
{
if ([data length] == 0) return data;
z_stream strm;
strm.zalloc = Z_NULL;
strm.zfree = Z_NULL;
strm.opaque = Z_NULL;
strm.total_out = 0;
strm.next_in=(Bytef *)[data bytes];
strm.avail_in = [data length];
// Compresssion Levels:
// Z_NO_COMPRESSION
// Z_BEST_SPEED
// Z_BEST_COMPRESSION
// Z_DEFAULT_COMPRESSION
if (deflateInit2(&strm, Z_DEFAULT_COMPRESSION, Z_DEFLATED, (15+16), 8, Z_DEFAULT_STRATEGY) != Z_OK) return nil;
NSMutableData *compressed = [NSMutableData dataWithLength:16384]; // 16K chunks for expansion
do {
if (strm.total_out >= [compressed length])
[compressed increaseLengthBy: 16384];
strm.next_out = [compressed mutableBytes] + strm.total_out;
strm.avail_out = [compressed length] - strm.total_out;
deflate(&strm, Z_FINISH);
} while (strm.avail_out == 0);
deflateEnd(&strm);
[compressed setLength: strm.total_out];
return [NSData dataWithData:compressed];
}
However, the uncompressMe function doesnt seem to succeed. It fails in the Inflate method, which always returns a nil. Any thoughts what I might be doing wrong? I have checked to make sure that the blob column does get populated.
I feel like issue is from below code:
NSUInteger len = sqlite3_value_bytes(aargv[0]);
Byte *byteData = (Byte*)malloc(len);
memcpy(byteData, sqlite3_value_blob(aargv[0]), len);
NSData *data = [[NSData alloc] initWithBytes:byteData length:len];
Try this to load NSData from database instead of creating byte variable and copying it.
const void *bytes = sqlite3_column_blob(statement, 3);
NSData *data = [[NSData alloc] initWithBytes:bytes length:size];

Gamekit Framework: sending an int?

Hi I am building a game that uses the gamekit framework but I am having trouble sending to int using the "sendDataToAllPlayers", it cannot distinguish between the two int that I am sending. Here is some of my code:
typedef enum {
kMessageTypeRandomNumber = 0,
kMessageQN = 0,
kMessageTypeGameBegin,
kMessageTypeSelectAnswer1,
kMessageTypeSelectAnswer2,
kMessageTypeSelectAnswer3,
kMessageTypeGameOver
} MessageType;
typedef struct {
MessageType messageType;
} Message;
typedef struct {
Message message;
uint32_t randomNumber;
int SelectedQ;
} MessageRandomNumber;
the following is the send methods:
-(void)sendTheSelectedRandomQuestionWithQuestion {
MessageRandomNumber message;
message.message.messageType = kMessageQN;
message.SelectedQ = randomSelectedQuestion;
NSData *data = [NSData dataWithBytes:&message length:sizeof(MessageRandomNumber)];
[self sendData:data];
}
- (void)sendRandomNumber {
//ourRandom = arc4random()%100;
MessageRandomNumber message;
message.message.messageType = kMessageTypeRandomNumber;
message.randomNumber = ourRandom;
NSData *data = [NSData dataWithBytes:&message length:sizeof(MessageRandomNumber)];
[self sendData:data];
}
- (void)sendData:(NSData *)data {
NSError *error;
BOOL success = [[GCHelper sharedInstance].match sendDataToAllPlayers:data withDataMode:GKMatchSendDataReliable error:&error];
if (!success) {
NSLog(#"Error sending init packet");
[self matchEnded];
}
}
the following is the didreceivedatamethod:
- (void)match:(GKMatch *)match didReceiveData:(NSData *)data fromPlayer:(NSString *)playerID {
//Store away other player ID for later
if (otherPlayerID == nil) {
otherPlayerID = playerID;
}
Message *message = (Message *) [data bytes];
if (message->messageType == kMessageQN) {
NSLog(#"Received The Selected Question To Display");
debugLabel.text = #"received the selected q";
MessageRandomNumber * messageSelectedQuestion = (MessageRandomNumber *) [data bytes];
NSLog(#"The Selected Question is number: %ud",messageSelectedQuestion->SelectedQ);
randomSelectedQuestion = messageSelectedQuestion->SelectedQ;
[self displayTheSlectedQuestion];
} else if (message->messageType == kMessageTypeRandomNumber) {
MessageRandomNumber * messageInit = (MessageRandomNumber *) [data bytes];
NSLog(#"Received random number: %ud, ours %ud", messageInit->randomNumber, ourRandom);
bool tie = false;
if (messageInit->randomNumber == ourRandom) {
//NSLog(#"TIE!");
ourRandom = arc4random();
tie = true;
[self sendRandomNumber];
} else if (ourRandom > messageInit->randomNumber) {
NSLog(#"We are player 1");
isPlayer1 = YES;
//[self sendTheSelectedRandomQuestionWithQuestion];
} else {
NSLog(#"We are player 2");
isPlayer1 = NO;
}
if (!tie) {
receivedRandom = YES;
if (gameState == kGameStateWaitingForRandomNumber) {
[self setGameState:kGameStateWaitingForStart];
}
[self tryStartGame];
}
}
}
}
but for some mysterious reason every time I call the sendTheSelectedRandomQuestionWithQuestion when it is received it thinks that it is randomNumber and not SelectedQ? Can anyone help me please?
Ok, just figured out the problem. It should be:
typedef enum {
kMessageTypeRandomNumber = 0,
kMessageQN = 1,
kMessageTypeGameBegin,
kMessageTypeSelectAnswer1,
kMessageTypeSelectAnswer2,
kMessageTypeSelectAnswer3,
kMessageTypeGameOver
} MessageType;
Instead of:
typedef enum {
kMessageTypeRandomNumber = 0,
kMessageQN = 0,
kMessageTypeGameBegin,
kMessageTypeSelectAnswer1,
kMessageTypeSelectAnswer2,
kMessageTypeSelectAnswer3,
kMessageTypeGameOver
} MessageType;

Resources