How to convert nsstring to nsdictionary? - objective-c

I have gone through following question.
Convert NSString to NSDictionary
It is something different then my question.
My question is as follows.
NSString *x=#"<Category_Id>5</Category_Id><Category_Name>Motos</Category_Name><Category_Picture>http://192.168.32.20/idealer/admin/Picture/icon_bike2009819541578.png</Category_Picture>";
Now I want to convert this into a dictionary, something like this,
dictionary key = Category_Id | value = 5
dictionary key = Category_Name | value = ???
dictionary key = Category_Picture | value = ???
I don't know how to perform this.

Not the fastest implementation, but this would do the trick (and doesn’t require any third party libraries):
#interface NSDictionary (DictionaryFromXML)
+ (NSDictionary *)dictionaryFromXML:(NSString *)xml;
#end
#implementation NSDictionary (DictionaryFromXML)
+ (NSDictionary *)dictionaryFromXML:(NSString *)xml
{
// We need to wrap the input in a root element
NSString *x = [NSString stringWithFormat:#"<x>%#</x>", xml];
NSXMLDocument *doc = [[[NSXMLDocument alloc] initWithXMLString:x
options:0
error:NULL]
autorelease];
if (!doc)
return nil;
NSMutableDictionary *dict = [NSMutableDictionary dictionary];
for (NSXMLElement *el in [[doc rootElement] children])
[dict setObject:[el stringValue] forKey:[el name]];
return dict;
}
#end

If it's XML then you can use an NSXMLParser. If it's not then you can write your own parser.

You could do it with a regular expression... Something like <([^>]+)>([^<]+)</\1> would grab the key into capture 1 and the value into capture 2. Iterate over the matches and build the dictionary.
This uses RegexKitLite:
NSString * x = #"<Category_Id>5</Category_Id><Category_Name>Motos</Category_Name><Category_Picture>http://192.168.32.20/idealer/admin/Picture/icon_bike2009819541578.png</Category_Picture>";
NSString * regex = #"<([^>]+)>([^<]+)</\\1>";
NSArray * cap = [x arrayOfCaptureComponentsMatchedByRegex:regex];
NSMutableDictionary * d = [NSMutableDictionary dictionary];
for (NSArray * captures in cap) {
if ([captures count] < 3) { continue; }
NSString * key = [captures objectAtIndex:1];
NSString * value = [captures objectAtIndex:2];
[d setObject:value forKey:key];
}
NSLog(#"%#", d);

Related

Extracting number from NSString

I have an NSString which when logged gives me an answer like this one:
Response: oauth_token_secret=6h8hblp42jfowfy&oauth_token=9tmqsojggieln6z
The two numbers change every single time.
Is there a way to extract the two numbers and create two strings with one of each??
Like:
NSString *key = #"9tmqsojggieln6z";
//copy the string in a new string variable
NSMutableString *auth_token = [NSMutableString stringWithString:response];
NSRange match = [auth_token rangeOfString: #"&oauth_token="];
[auth_token deleteCharactersInRange: NSMakeRange(0, match.location+13)];
//auth_token will now have the auth token string
NSMutableString *auth_token_secret = [NSMutableString stringWithString:response];
NSRange range1 = [auth_token_secret rangeOfString:[NSString stringWithFormat:#"&oauth_token=%#", auth_token]];
[auth_token_secret deleteCharactersInRange:range1];
NSRange range2 = [auth_token_secret rangeOfString:#"oauth_token_secret="];
[auth_token_secret deleteCharactersInRange: range2];
//auth_token_secret will have the required secret string.
I had the same problem. As response I get the ids of objects sometimes as string sometimes as numbers. Then I wrote a category for NSDictionary which has the following method:
- (NSString *)stringFromStringOrNumberForKey:(NSString *)key
{
id secret = [self objectForKey:key];
if ([secret isKindOfClass:[NSNumber class]]) {
NSNumberFormatter * numberFormatter = [[NSNumberFormatter alloc] init];
secret = [numberFormatter stringFromNumber:secret];
}
return secret;
}
I would try the following:
NSString *_response = #"oauth_token_secret=6h8hblp42jfowfy&oauth_token=9tmqsojggieln6z";
NSMutableDictionary *_dictionary = [[NSMutableDictionary alloc] init];
NSArray *_parameters = [_response componentsSeparatedByString:#"&"];
for (NSString *_oneParameter in _parameters) {
NSArray *_keyAndValue = [_oneParameter componentsSeparatedByString:#"="];
[_dictionary setValue:[_keyAndValue lastObject] forKey:[_keyAndValue objectAtIndex:0]];
}
// reading the values
NSLog(#"token_secret : %#", [_dictionary valueForKey:#"oauth_token_secret"]);
NSLog(#"token : %#", [_dictionary valueForKey:#"oauth_token"]);

JSON text and variable count

I am reading like this...
NSString *fileContent = [[NSString alloc] initWithContentsOfFile:path];
SBJsonParser *parser = [[SBJsonParser alloc] init];
NSDictionary *data = (NSDictionary *) [parser objectWithString:fileContent error:nil];
// getting the data from inside of "menu"
NSString *message = (NSString *) [data objectForKey:#"message"];
NSString *name = (NSString *) [data objectForKey:#"name"];
NSArray *messagearray = [data objectForKey:#"message"];
NSArray *namearray = [data objectForKey:#"name"];
NSDictionary* Dictionary = [NSDictionary dictionaryWithObjects:message forKeys:name];
for (NSString* Key in [Dictionary allKeys]){
NSLog(#"%# %#",Key,[Dictionary objectForKey:Key]);
}
...this JSON file...
{"message":["Untitled1a","Untitled2a","Untitled3a"],"name": ["Untitled1b","Untitled2b","Untitled3b"]}
...this is the result...
Untitled3b Untitled3a
2012-05-12 11:31:17.983 Quick Homework[721:f803] Untitled1b Untitled1a
2012-05-12 11:31:17.983 Quick Homework[721:f803] Untitled2b Untitled2a
...but for each pair (Untitled 1b 2b) I would like to alloc two UITextFields, witch display the correspondent text...
I tried using this method:
for (NSString *string in messagearray){
}do{
NSLog(#"happt = %i", b);
b++;
}
while(b == b);
//While loop
while (b == b ) {
NSLog(#"x = %i", b);
b++;
}
}
I would like to count the objects in the array in order to repeat an alloc code for UITextField that number of times, and display the text accordingly, but I am not able. Please help!!
Why can't you use -count?
b = [messagearray count]
To directly answer your question:
b = 0;
for (id item in messagearray)
b++;

how to create a NSDictionary consisting of NSArray of NString for key and bunch of int for the value?

here is the problem :
NSArray * alphabets = [NSArray arrayWithObjects:#"a",#"b",#"c",#"d",#"e",#"f",#"g",#"h",#"i",#"j",#"k",#"l",#"m",#"n",#"o",#"p",#"q",#"r",#"s",#"t",#"u",#"v",#"w",#"x",#"y",#"z",nil];
NSDictionary * alphaToNum = [NSDictionary dictionaryWithObject:alphabets forKey:1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26];
//I know above line meant to not work I just brought it here as an example
how can I create a dictionary just like above which is working?
You can only use objects as keys or values in a NSDictionary, so you have to use NSNumber as wrapper for your integer key.
NSMutableDictionary *alphaToNum = [NSMutableDictionary dictionary];
NSArray *alphabet = [NSArray arrayWithObjects:#"a",#"b",#"c",#"d",#"e",#"f",#"g",#"h",#"i",#"j",#"k",#"l",#"m",#"n",#"o",#"p",#"q",#"r",#"s",#"t",#"u",#"v",#"w",#"x",#"y",#"z",nil];
NSInteger index = 0;
for(NSString *character in alphabet)
{
index ++;
[alphaToNum setObject:character forKey:[NSNumber numberWithInteger:index]];
}

can't get value from NSDictionary which expected to have NSNumber as output

I have created a NSDictionary like following :
NSArray * alphabets = [NSArray arrayWithObjects:#"a",#"b",#"c",#"d",#"e",#"f",#"g",#"h",#"i",#"j",#"k",#"l",#"m",#"n",#"o",#"p",#"q",#"r",#"s",#"t",#"u",#"v",#"w",#"x",#"y",#"z",nil];
alphaToNum = [NSMutableDictionary dictionary];
numToAlpha = [NSMutableDictionary dictionary];
for(NSString* character in alphabets)
{
[alphaToNum setObject:[NSNumber numberWithInteger:index] forKey:character];
[numToAlpha setObject:character forKey:[NSNumber numberWithInteger:index]];
index++;
}
now I want to access to "numToAlpha" like following :
NSInteger code1;
NSNumber * nn = [numToAlpha objectForKey:code1];
and I'll get error whereas in manual for objectforkey it clearly said (id)objectforkey(id) which means anything!
NSInteger is not an object. id refers to any object type. You need to use [NSNumber numberWithInteger:code1] as you are already doing in your code sample.

complex JSON parsing using Objective-C

{
"Flight1":{
"3":{
"id":"10",
"name":"JumboJet1B",
"level":"1",
"category":"1",
"energy":"10",
"bonus":"10",
"completed":0
},
"4":{
"id":"10",
"name":"JumboJet1B",
"level":"1",
"category":"1",
"energy":"10",
"bonus":"10",
"completed":0
}
}
}
This was the json output
How can I parse inside the items of 3 and 4, say getting the id, energy and name
Thanks!
If the order inside Flight1 doesn’t matter, the following should work:
NSDictionary *flights = … // result from a JSON parser
NSDictionary *flight1 = [flights objectForKey:#"Flight1"];
for (NSString *key in [flight1 allKeys]) {
NSDictionary *flight1Entry = [flight1 objectForKey:key];
NSString *entryId = [flight1Entry objectForKey:#"id"];
NSString *entryName = [flight1Entry objectForKey:#"name"];
NSString *entryEnergy = [flight1Entry objectForKey:#"energy"];
…
}
Otherwise, if you want the keys sorted according to their numeric value:
NSDictionary *flights = … // result from a JSON parser
NSDictionary *flight1 = [flights objectForKey:#"Flight1"];
NSArray *flight1Keys = [[flight1 allKeys] sortedArrayUsingComparator:^(id o1, id o2) {
NSInteger i1 = [o1 integerValue];
NSInteger i2 = [o2 integerValue];
NSComparisonResult result;
if (i1 > i2) result = NSOrderedDescending;
else if (i1 < i2) result = NSOrderedAscending;
else result = NSOrderedSame;
return result;
}];
for (NSString *key in flight1Keys) {
NSDictionary *flight1Entry = [flight1 objectForKey:key];
NSString *entryId = [flight1Entry objectForKey:#"id"];
NSString *entryName = [flight1Entry objectForKey:#"name"];
NSString *entryEnergy = [flight1Entry objectForKey:#"energy"];
…
}
Assuming that you are using the json framework you could access it like this:
NSDictionary *jsonDict = [jsonString JSONValue];
NSString *id = [[[jsonDict objectForKey:#"Flight1"] objectForKey:#"3"] objectForKey:#"id"];
This assumes alot, so make use of try except blocks or iterate through the different levels.