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 ;)

Resources