Opening a strait binary file with iOS - ios
I wrote a custom file type that data from my Java program gets saved to. I want to get the data out on an iPod/Pad/Phone. So far I wrote this file for reading strait byte values from a file and changing them into NSStrings and integers.
#import "BinaryFileReader.h"
#implementation BinaryFileReader
- (id)init {
self = [super init];
return self;
}
- (id)initWithLocation:(NSString*)filepath {
if ((self = [super init])) {
_file = [NSFileHandle fileHandleForReadingAtPath:filepath];
_fileOffset = 0;
if (_file == nil)
NSLog(#"%#%#",#"Failed to open file at path:",filepath);
}
return self;
}
- (void)close {
[_file closeFile];
}
- (int)readInt {
[_file seekToFileOffset:_fileOffset];
_databuffer = [_file readDataOfLength:4];
_fileOffset+=4;
return (int)[_databuffer bytes];
}
- (NSString*)readNSString {
int length = [self readInt];
[_file seekToFileOffset:_fileOffset];
_databuffer = [_file readDataOfLength:length];
_fileOffset+=length;
return [[NSString alloc] initWithData:_databuffer encoding:NSUTF8StringEncoding];
}
- (NSMutableArray*)readNSMutableArrayOfNSString {
NSMutableArray* array = [[NSMutableArray alloc] init];
int arrayLength = [self readInt];
int length;
for (int i=0; i<arrayLength; i++) {
length = [self readInt];
[_file seekToFileOffset:_fileOffset];
_databuffer = [_file readDataOfLength:length];
_fileOffset+=length;
[array addObject:[[NSString alloc] initWithData:_databuffer encoding:NSUTF8StringEncoding]];
}
return array;
}
#end
Now when I try to use this to read NSStrings or integers it does not come up with the right values. I assume since both NSStrings and integers are coming up wrong it's something in the readInt method. Anyone see something glaringly obvious that I've missed here?
Edit:
The file format that I am trying to read starts with a string. That string, when read with readNSString, is the correct string but the first 1/3 of the string is missing.
Java code:
public void saveItem() {
try {
byte[] bytes;
FileOutputStream output;
if (countOccurrences(location.getPath(),'.')==1) {
System.out.println("Option 1");
output = new FileOutputStream(location+"/"+name+".dtb");
} else {
output = new FileOutputStream(location);
}
bytes = name.getBytes("UTF-8");
output.write(bytes.length);
output.write(bytes);
output.write(otherNames.length);
for (int i=0;i<otherNames.length;i++) {
bytes = otherNames[i].getBytes("UTF-8");
output.write(bytes.length);
output.write(bytes);
}
bytes = description.getBytes("UTF-8");
output.write(bytes.length);
output.write(bytes);
bytes = XactCode.getBytes("UTF-8");
output.write(bytes.length);
output.write(bytes);
bytes = SymbilityCode.getBytes("UTF-8");
output.write(bytes.length);
output.write(bytes);
output.write(averageLowPrice);
output.write(averageHighPrice);
output.write(averageLifeExpectancy);
output.close();
bytes = null;
} catch (Exception e) {
e.printStackTrace();
}
}
The reason this does not work is the way you are casting the NSData to int. The bytes methods returns a pointer to the actual data, which you will need to deference to get the actual value (otherwise you will just be getting the memory address of the pointer).
I tried two ways:
int test = 64;
NSData *data = [NSData dataWithBytes:&test length:4];
int test2 = (int)[data bytes]; //This gave me 170382992
and
int test = 64;
NSData *data = [NSData dataWithBytes:&test length:4];
int test2 = *((int *)[data bytes]); //This gave me 64
Related
how to re-encode data from CFFTPCreateParsedResourceListing function?
i try to communicate with FTP server using CFNetwork.framework. using CFFTP API(CFWriteStreamCreateWithFTPURL function), i get a NSData of specific URL. then i start to parse the NSData with CFFTPCreateParsedResourceListing function, it gives me poorly encoded filenames.(when the file name is Korean) all character in Korean is converted to question mark(?). how can i fix this? please give me some advice. thank you in advance. NSMutableArray * newEntries; NSUInteger offset; newEntries = [NSMutableArray array]; assert(newEntries != nil); offset = 0; do { CFIndex bytesConsumed; CFDictionaryRef thisEntry; thisEntry = NULL; assert(offset <= [self.listData length]); bytesConsumed = CFFTPCreateParsedResourceListing(NULL, &((const uint8_t *) self.listData.bytes)[offset], (CFIndex) ([self.listData length] - offset), &thisEntry); if (bytesConsumed > 0) { if (thisEntry != NULL) { NSDictionary * entryToAdd; entryToAdd = [self entryByReencodingNameInEntry:(__bridge NSDictionary *) thisEntry encoding:NSUTF8StringEncoding]; [newEntries addObject:entryToAdd]; } offset += (NSUInteger) bytesConsumed; } if (thisEntry != NULL) { CFRelease(thisEntry); } if (bytesConsumed == 0) { break; } else if (bytesConsumed < 0) { [self stopReceiveWithStatus:#"Listing parse failed"]; break; } } while (YES); below code is entryByReencodingNameInEntry method NSDictionary * result; NSString * name; NSData * nameData; NSString * newName; newName = nil; // Try to get the name, convert it back to MacRoman, and then reconvert it // with the preferred encoding. name = [entry objectForKey:(id) kCFFTPResourceName]; if (name != nil) { assert([name isKindOfClass:[NSString class]]); nameData = [name dataUsingEncoding:NSMacOSRomanStringEncoding]; if (nameData != nil) { newName = [[NSString alloc] initWithData:nameData encoding:newEncoding]; } } if (newName == nil) { assert(NO); // in the debug builds, if this fails, we should investigate why result = (NSDictionary *) entry; } else { NSMutableDictionary * newEntry; newEntry = [entry mutableCopy]; assert(newEntry != nil); [newEntry setObject:newName forKey:(id) kCFFTPResourceName]; result = newEntry; } return result; for example, if a folder has 3 files 애플.txt, 삼성.txt, 테스트.txt -> converted to ??.txt, ??.txt, ???.txt
Apple Pay Integration using Cybersource
I am Integrating Apple Pay Integration using cyberSource in my Application . what i have done so for . 1- I have created merchant ID 2- I have created test account on http://www.cybersource.com/ 3- I have downloaded cybersource SDK for iOS. 4- I have managed to run Demo Application downloaded with SDK. 5- When i run demo App i am getting this error. "Transaction Details .Accepted: No .Auth Amount: (null) Error: Unknown error" I have provided my merchant account correctly . There are other fields as well which i am not sure how to get those values static NSString* kMetadataEncodedValue = #"RklEPUNPTU1PTi5MRy5JTkFQUC5QQVlNRU5U"; static NSString* const kPaymentSolutionDefaultValue = #"001"; static NSString* const kEnvTest = #"test"; static NSString* const kEnvLive = #"live"; static NSString* const kKeyMerchantID = #"merchant_otm_eyebuy_acct"; static NSString* const kKeyMerchantExternalID = #"merchant_otm_eyebuy_acct"; static NSString* const kKeyTransactionKey = #"transactionKey"; static NSString* const kKeyEncryptedBlob = #"encryptedBlob"; static NSString* const kKeyEnv = #"env"; - (IBAction)payButtonTouchDown:(id)sender { [self.amountTextField resignFirstResponder]; NSString* requestType = [self.requestTypeSelection titleForSegmentAtIndex:self.requestTypeSelection.selectedSegmentIndex]; [self updateStatusMessage:[NSString stringWithFormat:#"Submitting %# request...", requestType]]; self.payButton.enabled = NO; NSString *amountText = self.amountTextField.text; NSDecimalNumber *amountValue = [NSDecimalNumber decimalNumberWithString:amountText]; BOOL isDecimal = amountValue!= nil; if (isDecimal) { // TODO: Pass in encrypted payment data from PassKit [self performRequestWithEncryptedPaymentData:self.selectedAccountData[kKeyEncryptedBlob] withPaymentAmount:amountValue]; } else { self.payButton.enabled = YES; self.statusText.text = #"Enter valid Amount"; } } - (IBAction)requestTypeSelectionValueChanged:(UISegmentedControl *)sender { [self updateRequestSelection]; } -(void) updateRequestSelection { NSString* requestType = [self.requestTypeSelection titleForSegmentAtIndex:self.requestTypeSelection.selectedSegmentIndex]; [self updateStatusMessage:[NSString stringWithFormat:#"Tap '%#' to %# request.", self.payButton.currentTitle, requestType]]; } - (void) updateStatusMessage: (NSString*) message { self.statusText.text = message; self.payButton.enabled = YES; } - (void)performRequestWithEncryptedPaymentData: (NSString*) encryptedPaymentData withPaymentAmount: (NSDecimalNumber*) paymentAmount { VMposItem *item = [[VMposItem alloc] init]; item.name = NSLocalizedString(#"Item no 1", nil); item.price = paymentAmount; VMposTransactionObject *transactionObject = [VMposTransactionObject createTransaction:VMPOS_TRANSACTION_PAYMENT]; [transactionObject addItem:item]; [transactionObject calculateTotals]; // TODO: Encrypted Payment is created by client application based // on specification from SOAP API. The following values are just place holders VMposEncryptedPayment* payment = [VMposEncryptedPayment new]; payment.encodedData = encryptedPaymentData; payment.encodedMetadata = kMetadataEncodedValue; payment.paymentSolution = kPaymentSolutionDefaultValue; // Purchase details VMposPurchaseDetails* purchaseDetails = [VMposPurchaseDetails new]; purchaseDetails.partialIndicator = NO; // Sample Billing information VMposAddress* billTo = [VMposAddress new]; billTo.firstName = #"John"; billTo.lastName = #"Doe"; billTo.email = #"john.doe#yahoo.com"; billTo.street1 = #"1234 Pine St."; billTo.city = #"Redmond"; billTo.state = #"WA"; billTo.postalCode = #"98052"; billTo.country = #"US"; // Save transaction information transactionObject.encryptedPayment = payment; transactionObject.purchaseDetails = purchaseDetails; transactionObject.purchaseDetails.commerceIndicator = #"internet"; transactionObject.transactionCode = #"ref_code_12345678"; transactionObject.billTo = billTo; // Build fingerprint //--WARNING!---------------- // Finger print generation requires the transaction key. This should // be done at the server. It is shown here only for Demo purposes. NSString* merchantID = self.selectedAccountData[kKeyMerchantID]; NSString* fingerprint = [self buildFingerprintWithTransaction:transactionObject withMerchantId:merchantID]; NSLog(#"Fingerprint: %#", fingerprint); VMposGateway* gateway = [VMposGateway sharedInstance]; [gateway initSessionWithUserName:merchantID withMerchantId:merchantID withFingerprint: fingerprint withDelegate:self]; if (self.selectedAccountData[kKeyEnv] == kEnvLive) { [VMposSettings sharedInstance].cybsEnvironment = ENV_LIVE; } else { [VMposSettings sharedInstance].cybsEnvironment = ENV_TEST; } if (self.requestTypeSelection.selectedSegmentIndex == 0) { [gateway performAuthorizationWithTransaction:transactionObject withDelegate:self]; } else { [gateway performSaleWithTransaction:transactionObject withDelegate:self]; } } - (void)viewDidLoad { [super viewDidLoad]; [self configureAccounts]; [self updateStatusMessage:[NSString stringWithFormat:#"Tap '%#' to submit a test request.", self.payButton.currentTitle]]; self.amountTextField.keyboardType = UIKeyboardTypeDecimalPad; self.amountTextField.text = #"1.09"; [self.requestTypeSelection setSelectedSegmentIndex:0]; } - (void)didReceiveMemoryWarning { [super didReceiveMemoryWarning]; // Dispose of any resources that can be recreated. } // returns the number of 'columns' to display. - (NSInteger)numberOfComponentsInPickerView:(UIPickerView *)pickerView { return 1; } // returns the # of rows in each component.. - (NSInteger)pickerView:(UIPickerView *)pickerView numberOfRowsInComponent:(NSInteger)component { return self.configuredAccounts.count; } - (NSString *)pickerView:(UIPickerView *)pickerView titleForRow:(NSInteger)row forComponent:(NSInteger)component { NSDictionary* rowData = self.configuredAccounts[row]; return [NSString stringWithFormat:#"%# (%#)", rowData[kKeyMerchantID], rowData[kKeyEnv]]; } - (void)pickerView:(UIPickerView *)pickerView didSelectRow:(NSInteger)row inComponent:(NSInteger)component { self.selectedAccountData = self.configuredAccounts[row]; } //! Callback for user session initialization - (void) didInitUserSession: (VMposUserSession*) paramUserSession withError:(VMposError*)paramError { } //! provides feedback from finished authorization transaction request /*! \param paramResponseData gateway data retrieved from server (contains information about transaction status) \param paramError an error if request failed */ - (void) authorizationFinishedWithGatewayResponse:(VMposGatewayResponse *)paramResponseData withError:(VMposError *)paramError { self.authorized = YES; [self updateStatusMessageWithResponse: (VMposGatewayResponse *)paramResponseData withError: paramError]; } //! provides feedback from finished sale request /*! \param paramResponseData gateway data retrieved from server (contains information about transaction status) \param paramError an error if request failed */ - (void) saleFinishedWithGatewayResponse:(VMposGatewayResponse *)paramResponseData withError:(VMposError *)paramError { self.authorized = YES; [self updateStatusMessageWithResponse: (VMposGatewayResponse *)paramResponseData withError: paramError]; } - (void) updateStatusMessageWithResponse: (VMposGatewayResponse *)paramResponseData withError: (NSError*) paramError { NSMutableString* s = [NSMutableString new]; if (paramResponseData) { [s appendString: #"\nTransaction Details:"]; [s appendFormat: #"\n * Accepted: %#", paramResponseData.isAccepted ? #"Yes" : #"No"]; [s appendFormat: #"\n * Auth Amount: %#", paramResponseData.authorizedAmount.stringValue]; } if (paramError) { [s appendFormat:#"\nError: %#", paramError.localizedDescription]; } [self updateStatusMessage:s]; } /* ----------WARNING!---------------- Finger print generation requires the transaction key. This should be done at the server. It is shown here only for Demo purposes. */ -(NSString*) buildFingerprintWithTransaction: (VMposTransactionObject*) transactionObject withMerchantId: (NSString*) merchantId { NSDate* dateNow = [NSDate date]; NSString* fingerprintDateString = [MPDemoViewController formatFingerprintDate:dateNow]; NSString* merchantTransKey = self.selectedAccountData[kKeyTransactionKey]; NSString* fgComponents = [NSString stringWithFormat:#"%#%#%#%#%#", [MPDemoViewController stringSha1:merchantTransKey], merchantId, transactionObject.transactionCode, [transactionObject.totalAmount gatewayPriceString], fingerprintDateString]; NSString* hashedFgComponents = [MPDemoViewController stringHmacSha256:fgComponents]; return [NSString stringWithFormat:#"%##%#", hashedFgComponents, fingerprintDateString]; } +(NSString*) formatFingerprintDate: (NSDate*) date { NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init]; NSTimeZone* tz = [NSTimeZone timeZoneWithName:#"UTC"]; [dateFormatter setDateFormat:#"yyyy-MM-dd'T'HH:mm:ss'Z'"]; [dateFormatter setTimeZone:tz]; return [dateFormatter stringFromDate:date]; } + (NSString *)stringSha1:(NSString *)value { const char *cstr = [value cStringUsingEncoding:NSUTF8StringEncoding]; NSData *data = [NSData dataWithBytes:cstr length:value.length]; uint8_t digest[CC_SHA1_DIGEST_LENGTH]; // This is an iOS5-specific method. // It takes in the data, how much data, and then output format, which in this case is an int array. CC_SHA1(data.bytes, (uint)data.length, digest); return [self stringHexEncode:digest withLength:CC_SHA1_DIGEST_LENGTH]; } + (NSString *)stringSha256:(NSString *)value { const char *cstr = [value cStringUsingEncoding:NSUTF8StringEncoding]; NSData *data = [NSData dataWithBytes:cstr length:value.length]; uint8_t digest[CC_SHA256_DIGEST_LENGTH]; // This is an iOS5-specific method. // It takes in the data, how much data, and then output format, which in this case is an int array. CC_SHA256(data.bytes, (uint)data.length, digest); return [self stringHexEncode:digest withLength:CC_SHA256_DIGEST_LENGTH]; } + (NSString *)stringHmacSha256:(NSString *)value { CCHmacContext ctx; const char* utf8ValueString = [value UTF8String]; uint8_t hmacData[CC_SHA256_DIGEST_LENGTH]; CCHmacInit(&ctx, kCCHmacAlgSHA256, utf8ValueString, strlen(utf8ValueString)); CCHmacUpdate(&ctx, utf8ValueString, strlen(utf8ValueString)); CCHmacFinal(&ctx, hmacData); return [self stringHexEncode:hmacData withLength:CC_SHA256_DIGEST_LENGTH]; } +(NSString*) stringHexEncode: (uint8_t*) data withLength: (NSInteger) dataLength { NSMutableString* output = [NSMutableString stringWithCapacity:dataLength * 2]; // Parse through the CC_SHA256 results (stored inside of digest[]). for(int i = 0; i < dataLength; i++) { [output appendFormat:#"%02x", data[i]]; } return output; } + (NSString*)base64forData:(NSData*)theData { const uint8_t* input = (const uint8_t*)[theData bytes]; NSInteger length = [theData length]; static char table[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/="; NSMutableData* data = [NSMutableData dataWithLength:((length + 2) / 3) * 4]; uint8_t* output = (uint8_t*)data.mutableBytes; NSInteger i; for (i=0; i < length; i += 3) { NSInteger value = 0; NSInteger j; for (j = i; j < (i + 3); j++) { value <<= 8; if (j < length) { value |= (0xFF & input[j]); } } NSInteger theIndex = (i / 3) * 4; output[theIndex + 0] = table[(value >> 18) & 0x3F]; output[theIndex + 1] = table[(value >> 12) & 0x3F]; output[theIndex + 2] = (i + 1) < length ? table[(value >> 6) & 0x3F] : '='; output[theIndex + 3] = (i + 2) < length ? table[(value >> 0) & 0x3F] : '='; } return [[NSString alloc] initWithData:data encoding:NSASCIIStringEncoding] ; } From where i can get all these values . it will be highly appreciated if some one in list all steps involved in Apple pay integration through CyberSource. Also Please do not refer me to apple developer as i have read out details about Apple Pay on Apple Developer.
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];
ios class_copyPropertyList return less count properties
I call class_copyPropertyList in my function + (NSDictionary *)classPropsFor:(Class)klass{ if (klass == NULL) { return nil; } NSMutableDictionary *results = [[NSMutableDictionary alloc] init] ; unsigned int outCount, i; objc_property_t *properties = class_copyPropertyList(klass, &outCount); for (i = 0; i < outCount; i++) { objc_property_t property = properties[i]; const char *propName = property_getName(property); if(propName) { const char *propType = getPropertyType(property); NSString *propertyName = [NSString stringWithUTF8String:propName]; NSString *propertyType = [NSString stringWithUTF8String:propType]; if (propertyType != nil){ [results setObject:propertyType forKey:propertyName]; } } } free(properties); // returning a copy here to make sure the dictionary is immutable return [NSDictionary dictionaryWithDictionary:results]; } But for example class with 2 properties it's get different count of properties list: one time 0 count, else time 2, else time 1. Why? This is happening on iOS 7
How do I convert a byte array to UIImage
I have a webservice which sends me back an array of bytes like this: <ax23:IMGBLOB>-119,80,78,71,13,10,26,10,0,0,0,13,73,72,68,82,0,0,0,100,0,0,0,106,8,3,0,0,0,125,54,4,22,0,0,0,51,80,76,84,69,0,0,0,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-73,-107,-30,-126,0,0,0,16,116,82,78,83,0,16,32,48,64,80,96,112,-128,-112,-96,-80,-64,-48,-32,-16,84,-32,-88,-56,0,0,2,126,73,68,65,84,120,-38,-19,90,65,-110,-124,32,12,4,68,64,69,-32,-1,-81,-35,-53,-78,-96,40,4,-79,-70,118,-86,-90,-113,51,106,-101,116,-120,33,-127,-3,43,72,101,-84,13,127,-80,-42,40,-7,42,-63,100,108,-72,-124,53,-45,75,38,-84,62,84,-32,-41,97,-125,-72,118,-95,9,-89,-7,0,-123,-56,-115,-88,-101,35,-98,90,-79,-122,14,-84,-113,-84,49,62,116,-63,-101,126,-71,-9,112,-58,-66,25,45,127,-95,-51,118,113,-127,-20,52,-29,124,-1,34,121,-31,78,-71,-100,-119,76,-113,-32,-5,-111,65,-117,-37,43,-11,-23,82,65,118,-107,63,40,42,91,-21,-24,-96,12,-47,101,-22,64,33,8,-122,31,104,20,-123,99,9,9,-106,104,-67,-80,-7,123,-79,38,-78,-73,114,51,35,99,118,29,44,-21,-45,-27,-59,-13,59,-87,-66,-14,-118,117,66,-91,120,89,104,-102,-69,7,57,124,114,20,-11,101,-118,119,-2,40,-37,-91,69,35,111,99,-60,-25,28,99,44,-2,46,46,-9,-100,99,-108,101,-81,-28,-85,-56,49,-50,98,-86,-126,56,-50,6,-64,93,41,75,-23,44,63,13,86,29,-2,-34,97,38,69,-33,32,-44,-83,-61,-72,-89,-26,4,122,102,-14,-68,-8,-93,16,100,80,-106,-14,-123,69,52,113,102,47,96,-114,79,19,-105,-122,88,-10,10,-74,43,83,-72,-49,-87,-57,33,-82,84,-47,45,-43,-71,-115,5,92,-97,-10,-102,37,-72,104,72,-43,126,111,120,-81,41,46,91,-20,-51,-16,-115,-9,-88,94,83,100,-15,-53,116,79,18,97,37,113,-35,23,-17,-19,99,30,-72,5,-79,-24,45,-77,-108,63,-77,-22,54,9,-67,-24,-43,39,-17,-104,40,123,-101,-124,94,-58,-120,83,2,-77,77,111,-79,112,-126,-99,-88,-2,-78,-57,39,24,2,73,-62,-62,-119,53,-5,49,-128,101,23,73,-16,21,9,-53,-57,-86,72,73,35,73,112,-110,17,-18,81,-71,93,59,-103,36,-63,-118,-74,40,38,-41,125,35,-112,-108,48,-68,-107,-118,109,78,98,-70,72,8,-27,-84,73,36,-55,119,68,18,-54,86,-79,-44,-102,16,92,44,84,-79,93,74,35,7,73,74,-97,1,72,66,-104,-21,36,60,102,-78,33,18,-53,10,8,8,9,-64,93,31,41,-4,90,13,97,-56,98,-124,-92,21,72,-126,28,77,-11,27,37,-43,67,62,90,-112,-49,47,-94,-112,24,40,-119,4,-71,36,-126,20,119,-112,50,21,89,112,-89,-51,68,-101,-60,78,-99,91,7,-56,38,8,-79,-99,-125,108,76,-79,91,-20,-9,-101,5,54,122,6,-46,-10,64,52,112,32,-83,40,68,83,13,-47,30,-124,52,58,17,45,91,68,-13,25,-46,70,71,12,4,16,-93,13,-64,-112,102,37,-113,-101,-74,-66,113,-45,22,18,7,98,112,6,29,1,-30,-121,-103,-8,-79,108,57,96,118,-75,1,-77,43,6,-52,-128,81,57,116,-24,-113,63,-66,-128,63,-120,-127,63,82,66,63,28,99,56,-2,-104,15,-2,-64,-46,-8,-47,-85,47,-66,-8,-30,-77,-16,3,-74,-58,-81,-89,-116,-22,56,-74,0,0,0,0,73,69,78,68,-82,66,96,-126,####</ax23:IMGBLOB> This array of bytes are used in Java for obtaining an image, I've been trying with several methods without success, I will post one of them below: -(UIImageView *)convierteImagen: (NSMutableString *)cadenaImagen{ //NSString to NSData (temporary) NSData *tempData = [cadenaImagen dataUsingEncoding:NSUTF8StringEncoding]; //NSLog(#"datos crudos: %#", tempData); //2.NSData to Bytes const void *bytes2 = [tempData bytes]; int8_t *bytes = (int8_t*)bytes2; int len = tempData.length; cadenaImagen = [[NSMutableString alloc]init]; [cadenaImagen appendString:#"["]; for (int i = 0; i < len; i++) { if (i) [cadenaImagen appendString:#","]; [cadenaImagen appendFormat:#"%d", bytes[i]]; } [cadenaImagen appendString:#"]"]; //3.Bytes to NSData NSData *datos2 = [NSData dataWithBytes:bytes length:len]; return [[UIImageView alloc]initWithImage:[UIImage imageWithData:datos2]]; } and the way I call this method is: - (void)viewDidLoad { [super viewDidLoad]; NSMutableString *imagen = [[NSMutableString alloc] initWithString:#"-119,80,78,71,13,10,26,10,0,0,0,13,73,72,68,82,0,0,0,100,0,0,0,106,8,3,0,0,0,125,54,4,22,0,0,0,51,80,76,84,69,0,0,0,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-73,-107,-30,-126,0,0,0,16,116,82,78,83,0,16,32,48,64,80,96,112,-128,-112,-96,-80,-64,-48,-32,-16,84,-32,-88,-56,0,0,2,126,73,68,65,84,120,-38,-19,90,65,-110,-124,32,12,4,68,64,69,-32,-1,-81,-35,-53,-78,-96,40,4,-79,-70,118,-86,-90,-113,51,106,-101,116,-120,33,-127,-3,43,72,101,-84,13,127,-80,-42,40,-7,42,-63,100,108,-72,-124,53,-45,75,38,-84,62,84,-32,-41,97,-125,-72,118,-95,9,-89,-7,0,-123,-56,-115,-88,-101,35,-98,90,-79,-122,14,-84,-113,-84,49,62,116,-63,-101,126,-71,-9,112,-58,-66,25,45,127,-95,-51,118,113,-127,-20,52,-29,124,-1,34,121,-31,78,-71,-100,-119,76,-113,-32,-5,-111,65,-117,-37,43,-11,-23,82,65,118,-107,63,40,42,91,-21,-24,-96,12,-47,101,-22,64,33,8,-122,31,104,20,-123,99,9,9,-106,104,-67,-80,-7,123,-79,38,-78,-73,114,51,35,99,118,29,44,-21,-45,-27,-59,-13,59,-87,-66,-14,-118,117,66,-91,120,89,104,-102,-69,7,57,124,114,20,-11,101,-118,119,-2,40,-37,-91,69,35,111,99,-60,-25,28,99,44,-2,46,46,-9,-100,99,-108,101,-81,-28,-85,-56,49,-50,98,-86,-126,56,-50,6,-64,93,41,75,-23,44,63,13,86,29,-2,-34,97,38,69,-33,32,-44,-83,-61,-72,-89,-26,4,122,102,-14,-68,-8,-93,16,100,80,-106,-14,-123,69,52,113,102,47,96,-114,79,19,-105,-122,88,-10,10,-74,43,83,-72,-49,-87,-57,33,-82,84,-47,45,-43,-71,-115,5,92,-97,-10,-102,37,-72,104,72,-43,126,111,120,-81,41,46,91,-20,-51,-16,-115,-9,-88,94,83,100,-15,-53,116,79,18,97,37,113,-35,23,-17,-19,99,30,-72,5,-79,-24,45,-77,-108,63,-77,-22,54,9,-67,-24,-43,39,-17,-104,40,123,-101,-124,94,-58,-120,83,2,-77,77,111,-79,112,-126,-99,-88,-2,-78,-57,39,24,2,73,-62,-62,-119,53,-5,49,-128,101,23,73,-16,21,9,-53,-57,-86,72,73,35,73,112,-110,17,-18,81,-71,93,59,-103,36,-63,-118,-74,40,38,-41,125,35,-112,-108,48,-68,-107,-118,109,78,98,-70,72,8,-27,-84,73,36,-55,119,68,18,-54,86,-79,-44,-102,16,92,44,84,-79,93,74,35,7,73,74,-97,1,72,66,-104,-21,36,60,102,-78,33,18,-53,10,8,8,9,-64,93,31,41,-4,90,13,97,-56,98,-124,-92,21,72,-126,28,77,-11,27,37,-43,67,62,90,-112,-49,47,-94,-112,24,40,-119,4,-71,36,-126,20,119,-112,50,21,89,112,-89,-51,68,-101,-60,78,-99,91,7,-56,38,8,-79,-99,-125,108,76,-79,91,-20,-9,-101,5,54,122,6,-46,-10,64,52,112,32,-83,40,68,83,13,-47,30,-124,52,58,17,45,91,68,-13,25,-46,70,71,12,4,16,-93,13,-64,-112,102,37,-113,-101,-74,-66,113,-45,22,18,7,98,112,6,29,1,-30,-121,-103,-8,-79,108,57,96,118,-75,1,-77,43,6,-52,-128,81,57,116,-24,-113,63,-66,-128,63,-120,-127,63,82,66,63,28,99,56,-2,-104,15,-2,-64,-46,-8,-47,-85,47,-66,-8,-30,-77,-16,3,-74,-58,-81,-89,-116,-22,56,-74,0,0,0,0,73,69,78,68,-82,66,96,-126"]; [self.view addSubview:[self convierteImagen:imagen]]; } Any help I will appreciate :)
try this: -(UIImageView *)convierteImagen: (NSMutableString *)cadenaImagen{ NSArray *strings = [cadenaImagen componentsSeparatedByString:#","]; unsigned c = strings.count; uint8_t *bytes = malloc(sizeof(*bytes) * c); unsigned i; for (i = 0; i < c; i++) { NSString *str = [strings objectAtIndex:i]; int byte = [str intValue]; bytes[i] = (uint8_t)byte; } NSData *datos = [NSData dataWithBytes:bytes length:c]; UIImage *image = [UIImage imageWithData:datos]; return [[UIImageView alloc]initWithImage:image]; } on viewdidLoad is the same code you put: - (void)viewDidLoad { [super viewDidLoad]; NSMutableString *imagen = [[NSMutableString alloc] initWithString:#"-119,80,78,71,13,10,26,10,0,0,0,13,73,72,68,82,0,0,0,100,0,0,0,106,8,3,0,0,0,125,54,4,22,0,0,0,51,80,76,84,69,0,0,0,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-73,-107,-30,-126,0,0,0,16,116,82,78,83,0,16,32,48,64,80,96,112,-128,-112,-96,-80,-64,-48,-32,-16,84,-32,-88,-56,0,0,2,126,73,68,65,84,120,-38,-19,90,65,-110,-124,32,12,4,68,64,69,-32,-1,-81,-35,-53,-78,-96,40,4,-79,-70,118,-86,-90,-113,51,106,-101,116,-120,33,-127,-3,43,72,101,-84,13,127,-80,-42,40,-7,42,-63,100,108,-72,-124,53,-45,75,38,-84,62,84,-32,-41,97,-125,-72,118,-95,9,-89,-7,0,-123,-56,-115,-88,-101,35,-98,90,-79,-122,14,-84,-113,-84,49,62,116,-63,-101,126,-71,-9,112,-58,-66,25,45,127,-95,-51,118,113,-127,-20,52,-29,124,-1,34,121,-31,78,-71,-100,-119,76,-113,-32,-5,-111,65,-117,-37,43,-11,-23,82,65,118,-107,63,40,42,91,-21,-24,-96,12,-47,101,-22,64,33,8,-122,31,104,20,-123,99,9,9,-106,104,-67,-80,-7,123,-79,38,-78,-73,114,51,35,99,118,29,44,-21,-45,-27,-59,-13,59,-87,-66,-14,-118,117,66,-91,120,89,104,-102,-69,7,57,124,114,20,-11,101,-118,119,-2,40,-37,-91,69,35,111,99,-60,-25,28,99,44,-2,46,46,-9,-100,99,-108,101,-81,-28,-85,-56,49,-50,98,-86,-126,56,-50,6,-64,93,41,75,-23,44,63,13,86,29,-2,-34,97,38,69,-33,32,-44,-83,-61,-72,-89,-26,4,122,102,-14,-68,-8,-93,16,100,80,-106,-14,-123,69,52,113,102,47,96,-114,79,19,-105,-122,88,-10,10,-74,43,83,-72,-49,-87,-57,33,-82,84,-47,45,-43,-71,-115,5,92,-97,-10,-102,37,-72,104,72,-43,126,111,120,-81,41,46,91,-20,-51,-16,-115,-9,-88,94,83,100,-15,-53,116,79,18,97,37,113,-35,23,-17,-19,99,30,-72,5,-79,-24,45,-77,-108,63,-77,-22,54,9,-67,-24,-43,39,-17,-104,40,123,-101,-124,94,-58,-120,83,2,-77,77,111,-79,112,-126,-99,-88,-2,-78,-57,39,24,2,73,-62,-62,-119,53,-5,49,-128,101,23,73,-16,21,9,-53,-57,-86,72,73,35,73,112,-110,17,-18,81,-71,93,59,-103,36,-63,-118,-74,40,38,-41,125,35,-112,-108,48,-68,-107,-118,109,78,98,-70,72,8,-27,-84,73,36,-55,119,68,18,-54,86,-79,-44,-102,16,92,44,84,-79,93,74,35,7,73,74,-97,1,72,66,-104,-21,36,60,102,-78,33,18,-53,10,8,8,9,-64,93,31,41,-4,90,13,97,-56,98,-124,-92,21,72,-126,28,77,-11,27,37,-43,67,62,90,-112,-49,47,-94,-112,24,40,-119,4,-71,36,-126,20,119,-112,50,21,89,112,-89,-51,68,-101,-60,78,-99,91,7,-56,38,8,-79,-99,-125,108,76,-79,91,-20,-9,-101,5,54,122,6,-46,-10,64,52,112,32,-83,40,68,83,13,-47,30,-124,52,58,17,45,91,68,-13,25,-46,70,71,12,4,16,-93,13,-64,-112,102,37,-113,-101,-74,-66,113,-45,22,18,7,98,112,6,29,1,-30,-121,-103,-8,-79,108,57,96,118,-75,1,-77,43,6,-52,-128,81,57,116,-24,-113,63,-66,-128,63,-120,-127,63,82,66,63,28,99,56,-2,-104,15,-2,-64,-46,-8,-47,-85,47,-66,-8,-30,-77,-16,3,-74,-58,-81,-89,-116,-22,56,-74,0,0,0,0,73,69,78,68,-82,66,96,-126"]; [self.view addSubview:[self convierteImagen: imagen]]; } this is what I got with your byte array: so I think this should solve your problem ;)