Blob to image conversion - objective-c

I am fetching result by fire a transaction but by the transaction one result is coming as blob attributes, that is image, I want to change that blob attribute to image
I wrote code for that "icon" is the key for fetch the image from transaction,
so please help me check this,
image is printing nil,
why?
NSString *inputString = [[[self formModel] attributeAsString:#"icon"] description];
NSLog(#"icon is %#",[[self formModel] attributeAsString:#"icon"]);
NSLog(#"inputstring is %#",inputString);
//NSImage *image = [NSUnarchiver unarchiveObjectWithData:[[self formModel] attributeAsString:#"icon"]];
//NSLog(#"image is %#",image);
NSArray *words = [inputString componentsSeparatedByString:#" "];
NSLog(#"words is %#",words);
NSArray *sizes = [words valueForKey:#"length"];
int sizeOfBytes = 0;
for (NSNumber *size in sizes) {
sizeOfBytes += [size intValue]/2;
}
int bytes[sizeOfBytes];
int counts = 0;
for (NSString *word in words) {
// convert each word from string to int
NSMutableString *ostr = [NSMutableString stringWithCapacity:[word length]];
while ([word length] > 0) {
[ostr appendFormat:#"%#", [word substringFromIndex:[word length] - 2]];
word = [word substringToIndex:[word length] - 2];
}
NSScanner *scaner = [NSScanner scannerWithString:ostr];
unsigned int val;
[scaner scanHexInt:&val];
bytes[counts] = val;
counts++;
}
// get NSData form c array
NSData *data = [NSData dataWithBytes:bytes length:sizeOfBytes];
NSLog(#"My NSDATA %#",data);
NSImage *Image = [[NSImage alloc] initWithData:data];

Never use the output of description to do processing. There is no guarantee of its format. What format is your original "blob" in and how was it generated? Your code suggests it might be an NSData or it might be an NSKeyArchiver. Both of these easily convert to NSData. You never need to do this by hand by converting to a string.

Related

Conversion from decrypted NSData to NSDictionary fails

I have to encrypt and scramble a NSDictionary and then unscramble and decrypt in another method. I have followed the instructions from Securely storing keys in iOS Application except that I'm not using a PLIST file to fill the NSDictionary values, but NSString values that are being inputed in the program and I'm doing this targeting OSX
The program can be divided in 3 parts:
Encryption: Encrypts the NSDictionary and returns a base64encoded NSString
Scramble: Scrambles the base64encoded key among the values of the previous NSString
Unscramble and Decryption
My problem is in the last decryption. The unscramble works just fine, but the decryption seems to produce NSData that can't be convertible into the original NSDictionary
Encryption
What I'm doing for encryption is:
Initialising a NSDictionary
Converting it to NSData via NSPropertyListSerialization and format NSPropertyListXMLFormat_v1_0
Encrypting this data using RNCryptor and a key
Returning the base64 representation of this NSData as NSString
The code for this part is:
+(NSString *)encrypt:(NSString *)firstValue secondValue:(NSString *)secondValue andKey:(NSString *)key;
{
NSDictionary *dictionary = [[NSDictionary alloc] initWithObjects:[[NSArray alloc] initWithObjects:firstValue, secondValue, nil] forKeys:[[NSArray alloc] initWithObjects:#"first", #"second", nil]];
NSData *data = [NSPropertyListSerialization dataFromPropertyList:dictionary format:NSPropertyListXMLFormat_v1_0 errorDescription:nil];
NSData *encryptData = [RNEncryptor encryptData:data withSettings:kRNCryptorAES256Settings password:key error:nil];
return [encryptData base64EncodedString];
}
Scramble
The second part of the process is to scramble the key in base64 among the characters of the data, I'm doing this by:
Converting the key to NSData using -(NSData *)dataUsingEncoding:
Converting this NSData to a base64encoded NSString
Inserting char of this NSString into a NSMutadedString in a particular order
Returning NSString from this NSMutadedString to be decrypted later
Here's the code for the scramble part:
+(NSString *)scrambleStrings:(NSString *)firstValue secondValue:(NSString *)secondValue andKey:(NSString *)key;
{
NSData *keyData = [key dataUsingEncoding:NSUTF8StringEncoding];
key = [keyData base64EncodedString];
// String from the first method
NSString *encrypt = [self encrypt:firstValue secondValue:secondValue andKey:key];
NSArray *myOrder = [self mySortAlgorithm:key];
NSMutableString *mutableEncrypt = [NSMutableString stringWithString:encrypt];
for(int i=0; i<[myOrder count];i++)
{
unichar c = [key characterAtIndex:i];
int index = [[myOrder objectAtIndex:i] intValue];
[mutableEncrypt insertString:[NSString stringWithCharacters:&c length:1] atIndex:index];
}
return [NSString stringWithString:mutableEncrypt];
}
Decryption
The third part consists of testing if I can decrypt and unscramble it to the original NSDictionary and NSString key. It basically consists of:
Retrieve the scrambled NSString from the second method
Separating the scrambled key from the dictionary NSData from the previous NSString
Decode the base64encode key (Works for sure 'till here)
Decode the base64encoded dictionary data
Decrypt the previous data using RNCryptor using the decoded key
Initialising a NSDictionary using the data from the last step
Output the NSDictionary values via NSLog
And Here's the code for this last part:
+(BOOL)testScrambleWithFirstValue:(NSString *)firstValue secondValue:(NSString *)secondValue andKey:(NSString *)key;
{
NSString *scrambledAndEncryptedKeys = [self scrambleFirstValue:firstValue secondValue:SecondValue andKey:key];
NSArray *myOrder = [self mySortAlgorithm:key];
NSMutableString *encryptedDictionary = [[NSMutableString alloc] init];
NSMutableString *encryptedKey = [[NSMutableString alloc] init];
for (int i=0; i<scrambledAndEncryptedKeys.length; i++) {
char c = [scrambledAndEncryptedKeys characterAtIndex:i];
if ([myOrder doesContain:[NSNumber numberWithInt:i]]) {
[encryptedKey appendFormat:#"%c", c];
} else {
[encryptedDictionary appendFormat:#"%c",c];
}
}
NSString *decryptedKey = [[NSString alloc] initWithData:[NSData dataFromBase64String:[NSString stringWithString:encryptedKey]] encoding:NSUTF8StringEncoding];
NSString *base64DataStr = [[NSString alloc] initWithData:[NSData dataFromBase64String:[NSString stringWithString:encryptedDictionary]] encoding:NSUTF8StringEncoding];
NSData *decryptedData = [RNDecryptor decryptData:[base64DataStr dataUsingEncoding:NSUTF8StringEncoding] withPassword:decryptedKey error:nil];
NSPropertyListFormat xmlFormat;
NSDictionary *decryptedDictionary = [NSPropertyListSerialization propertyListWithData:decryptedData options:NSPropertyListImmutable format:&xmlFormat error:nil];
//Outputs NULL
NSLog(#"decryptedDictionary:%#", decryptedDictionary);
//Just to simplify I'm returning YES here
return YES;
}
The problem is, that the last NSLog outputs a NULL value. Which makes me think that the NSData is not being decrypted.
I've been hammering my head over this since yesterday morning, so all the help is appreciated. Thanks in advance

Unable to convert UTF-8 text from NSDictionary in Objective-C

Im using foursquare API to get some locations around me, but when the name of that place wasn't in english, the name will be like follows:
name = "\U0645\U0633\U062c\U062f \U0627\U0644\U0633\U064a\U062f\U0629 \U0639\U0627\U0626\U0634\U0629 | Aisha Mosque";
i tried to convert the response to a UTF-8 but nothing changed.
Here is my code:
-(void)setUpLocations{
NSURL *url = [NSURL URLWithString: #"https://api.foursquare...."];
NSData *data = [NSData dataWithContentsOfURL:url];
NSError *error = nil;
NSDictionary *json = [NSJSONSerialization JSONObjectWithData:data options:0 error:&error];
NSLog(#"Response: %#",[[[json objectForKey:#"response"]objectForKey:#"groups"]valueForKey:#"items"]);
}
And the log result is:
contact = {
};
id = 51712507498ec4e8c5ae9f48;
likes = {
count = 0;
groups = (
);
};
location = {
address = Abdoun;
cc = JO;
city = Amman;
country = Jordan;
distance = 3819;
lat = "31.95406043797281";
lng = "35.88095228186612";
};
name = "\U0645\U0633\U062c\U062f \U0627\U0644\U0633\U064a\U062f\U0629 \U0639\U0627\U0626\U0634\U0629 | Aisha Mosque";
restricted = 1;
stats = {
checkinsCount = 43;
tipCount = 2;
usersCount = 23;
};
verified = 0;
},
Any Suggestions ??
EDIT:
here is how i extract the data from the dictionary:
NSDictionary *dic = [[[[json objectForKey:#"response"]objectForKey:#"groups"]valueForKey:#"items"] copy];
namesArray = [[NSArray alloc]initWithArray:[self removeWhiteSpaces:[dic valueForKey:#"name"]]];
-(NSArray *)removeWhiteSpaces:(NSDictionary *)dic{
NSString *str = [NSString stringWithFormat:#"%#",dic];
NSString *str2 = [str stringByReplacingOccurrencesOfString:#"\n" withString:#""];
NSString *secondString = [str2 stringByReplacingOccurrencesOfString:#" " withString:#""];
NSString *thirdString = [secondString stringByReplacingOccurrencesOfString:#"(" withString:#""];
NSString *forthString = [thirdString stringByReplacingOccurrencesOfString:#")" withString:#""];
NSString *fifthString = [forthString stringByReplacingOccurrencesOfString:#"\"" withString:#""];
NSArray *items = [fifthString componentsSeparatedByString:#","];
return items;
}
And in the UITableView:
cell.textLabel.text = [NSString stringWithFormat:#"Name: %# ",[namesArray objectAtIndex:indexPath.row] ];
Update
After trying #Martin R answer i got the same results:
NSDictionary *dic = [[[[json objectForKey:#"response"]objectForKey:#"groups"]valueForKey:#"items"] copy];
NSString *value =[dic valueForKey:#"name"];
NSLog(#"%#", value);
UILabel *lbl = [[UILabel alloc]initWithFrame:self.view.frame];
lbl.numberOfLines = 0;
lbl.text = [NSString stringWithFormat:#"%#",value];;
[self.view addSubview:lbl];
and here is an image of the result
There is no problem.
NSLog() calls the description method of NSDictionary and NSArray, and that prints all non-ASCII characters as \Unnnn escape sequence.
If you extract the string values from the dictionary and print that you will see
that everything is correct.
Simple example:
NSDictionary *dict = #{ #"currency": #"€" };
NSLog(#"%#", dict);
// Output: { currency = "\U20ac"; }
NSString *value = dict[#"currency"];
NSLog(#"%#", value);
// Output: €
UPDATE: The problem seems to be in your removeWhiteSpaces: method, because
NSString *str = [NSString stringWithFormat:#"%#",dic];
already uses the description method to convert the dictionary to a string,
and the following stringByReplacingOccurrencesOfString calls are a (sorry!) very bad
method to fix that.
You should access the dictionary keys with objectForKey instead, or enumerate
the dictionary with for (NSString *key in dic) { ... } and build the desired
array.
UPDATE 2: From the JSON data (posted in chat discussion) it seem that you just need
NSArray *itemsArray = json[#"response"][#"groups"][0][#"items];
NSArray *namesArray = [itemsArray valueForKey:#"name"];
Note that "groups" is an array with one element.
Try to use this one..
[NSString stringWithUTF8String:]

how to find number of images from file name?

i need to know how meny image's i have from the file name exp:
i have images call:
first file:
Splash_10001.jpg
last file:
Splash_10098.jpg
and i want to inset then to array..
for(int i = 1; i <= IMAGE_COUNT; i++)
{
UIImage* image = [UIImage imageNamed:[NSString stringWithFormat:#"%#%04d.%#",self.firstImageName,i,self.imageType]];
NSLog(#"%d",i);
[imgArray addObject:image];
}
i want to replace IMAGE_COUNT with number 98 but i need to get the numbre from the string the user send me : Splash_10098.jpg
i need to Separate the Splash_10098.jpg into: nsstring:Splash_1 int:0098 nsstring:jpg
10x all!
It depends what input are of the string is granted. In the following I would search for the dot and go backwards to the maximum of digits.
By the way I could only recommend to use the multi lingual NumberFormatter instead of relying on the default conversion.
NSString * input = #"Splash_19001.jpg";
NSRange r = [input rangeOfString:#"."];
if(r.location>4){
NSString * numberPart = [input substringWithRange: NSMakeRange(r.location-4,4)];
NSNumberFormatter *nf = [[NSNumberFormatter alloc] init];
[nf setNumberStyle:NSNumberFormatterDecimalStyle];
NSNumber * number = [nf numberFromString:numberPart];
int val = [number intValue];
NSLog(#"intValue=%d",val);
}
I think this is what you're looking for
NSString *stringUserSendsYou = #"Splash_10098.jpg";
int IMAGE_COUNT = [[[stringUserSendsYou stringByReplacingOccurrencesOfString:#"Splash_1" withString:#""] stringByReplacingOccurrencesOfString:#".jpg" withString:#""] integerValue];
If the number length is fixed in the suffix, it would make sense to use a substring instead of trying to remove the prefix. Strip the extension and grab the last x characters, convert those into an int with either intValue or the NSNumberFormatter suggested by iOS, although that might be unnecessary if you are sure of the format of the string.
NSString *userProvidedString = #"Splash_10001.jpg";
NSString *numberString = [userProvidedString stringByDeletingPathExtension];
NSUInteger length = [numberString length];
NSInteger numberLength = 4;
if (length < numberLength)
{
NSLog(#"Error in the string");
return;
}
numberString = [numberString substringWithRange: NSMakeRange(length - 4, 4)];
NSInteger integer = [numberString integerValue];
// Do whatever you want with the integer.
Using Regex(NSRegularExpression in iOS), this can be done very easily,
Check this out,
NSError *error = NULL;
NSString *originalString = #"Splash_10098.jpg";
NSString *regexString = #"([^\?]*_[0-9])([0-9]*)(.)([a-z]*)";
NSRegularExpression* regex = [NSRegularExpression regularExpressionWithPattern:regexString options:NSRegularExpressionCaseInsensitive error:&error];
NSTextCheckingResult *match = [regex firstMatchInString:originalString options:NSRegularExpressionCaseInsensitive range:NSMakeRange(0, [originalString length])];
NSLog(#"FileName: %#", [originalString substringWithRange:[match rangeAtIndex:1]]);
NSLog(#"Total Count: %#", [originalString substringWithRange:[match rangeAtIndex:2]]);
NSLog(#"File type: %#", [originalString substringWithRange:[match rangeAtIndex:4]]);
Result:
FileName: Splash_1
Total Count: 0098
File type: jpg

XOR'ing two hex values stored as an NSString?

here is yet another silly question from me!
NSString *hex1 = #"50be4f3de4";
NSString *hex2 = #"30bf69a299";
/* some stuff like result = hex1^hex2; */
NSString *result = #"6001269f7d";
I have a hex value as a string, stored in two diff. variables. i need to Xor them and the result should be in another string variables?
i tried them by converting string --> NSData --> bytes array --> xor'ing them ...but i have no success.....
thank you in advance...
You have to convert every character to Base16(for hexadecimal) format first.Then you should proceed with XORing those characters.You can use the strtol() function to achieve this purpose.
NSString *hex1 = #"50be4f3de4";
NSString *hex2 = #"30bf69a299";
NSMutableArray *hexArray1 = [self splitStringIntoChars:hex1];
NSMutableArray *hexArray2 = [self splitStringIntoChars:hex2];
NSMutableString *str = [NSMutableString new];
for (int i=0; i<[hexArray1 count]; i++ )
{
/*Convert to base 16*/
int a=(unsigned char)strtol([[hexArray1 objectAtIndex:i] UTF8String], NULL, 16);
int b=(unsigned char)strtol([[hexArray2 objectAtIndex:i] UTF8String], NULL, 16);
char encrypted = a ^ b;
NSLog(#"%x",encrypted);
[str appendFormat:#"%x",encrypted];
}
NSLog(#"%#",str);
Utility method that i used to split characters of the string
-(NSMutableArray*)splitStringIntoChars:(NSString*)argStr{
NSMutableArray *characters = [[NSMutableArray alloc]
initWithCapacity:[argStr length]];
for (int i=0; i < [argStr length]; i++)
{
NSString *ichar = [NSString stringWithFormat:#"%c", [argStr characterAtIndex:i ]];
[characters addObject:ichar];
}
return characters;
}
Hope it helps!!

opencv ios cvseq storage

I am intending to pre-load all the images that I have stored inside application. Pre-loading of images involves:
Read images from bundle.
Extract object descriptors using cvExtractSurf from opencv framework.
Store IPLImage with corresponding object descriptors and keypoints.
I am having an issue in creating a dictionary containing CvSeq* keys and CvSeq* descs.
Please suggest how to store these values in NSMutableDictionary.
-(void) preloadImages:(NSMutableDictionary *)dictionary{
NSArray *d = [[NSBundle mainBundle] pathsForResourcesOfType:#"png" inDirectory:nil];
CvSURFParams params = cvSURFParams(500, 1);
CvMemStorage* storage = cvCreateMemStorage(0);
for( int i=0;i<[d count];i++){
NSString *searchForMe = #"myapp.app/1";
NSString *s = [[NSString alloc] initWithString:[d objectAtIndex:i]];
NSRange range = [s rangeOfString:searchForMe];
if( range.location != NSNotFound ){
NSMutableDictionary *surfDict = [[NSMutableDictionary alloc] init];
NSString *substring = [s substringFromIndex:range.location];
substring = [substring stringByReplacingOccurrencesOfString:#"myapp.app/" withString:#""];
UIImage *testImage = [UIImage imageNamed:substring];
IplImage *iplTestImage = [OpenCVUtilities CreateGRAYIplImageFromUIImage:testImage];
CvSeq *keys = 0 ;
CvSeq *descs = 0;
cvExtractSURF( iplTestImage, 0, &keys, &descs, storage, params );
[surfDict setObject:(id)testImage forKey:#"uiImage"];
NSLog(#"Image name : %#", substring);
[dictionary setObject:surfDict forKey:[NSString stringWithFormat:#"%d",i]];
[dictionary setObject:(NSObject *)keys forKey:#"keys"]; // error here
[dictionary setObject:(NSObject *)descs forKey:#"descs"]; // error here
[surfDict release];
}
}
}
Create a class that has an instance variable of type cvseq, add your cvseq to the object, and add that class to the dictionary.