I have an iPhone application which gets a json string from a server and parses it. It contains some data and, eg. an array of comments. But I've noticed that the order of the json array is not preserved when I parse it like this:
// parse response as json
SBJSON *jsonParser = [SBJSON new];
NSDictionary *jsonData = [jsonParser objectWithString:jsonResponse error:nil];
NSDictionary* tmpDict = [jsonData objectForKey:#"rows"];
NSLog(#"keys coming!");
NSArray* keys = [tmpDict allKeys];
for (int i = 0;i< [keys count]; i++) {
NSLog([keys objectAtIndex:i]);
}
Json structure:
{
"pagerInfo":{
"page":"1",
"rowsPerPage":15,
"rowsCount":"100"
},
"rows":{
"18545":{
"id":"18545",
"text":"comment 1"
},
"22464":{
"id":"22464",
"text":"comment 2"
},
"21069":{
"id":"21069",
"text":"comment 3"
},
… more items
}
}
Does anyone know how to deal with this problem? Thank you so much!
In your example JSON there is no array but a dictionary. And in a dictionary the keys are by definition not ordered in any way. So you either need to change the code that generates the JSON to really use an array or sort the keys array in your Cocoa code, maybe like this:
NSArray *keys = [[tmpDict allKeys] sortedArrayUsingSelector: #selector(compare:)];
Using that sorted keys array you can then create a new array with the objects in the correct order:
NSMutableArray *array = [NSMutableArray arrayWithCapacity: [keys count]];
for (NSString *key in keys) {
[array addObject: [tmpDict objectForKey: key]];
}
Cocoprogrmr,
Here's what you need to do: after you have parsed out your json string and loaded that into a NSArray (i.e. where you have NSArray* keys written above), from there you could put that into a for loop where you iterate over the values in your keys array. Next, to get your nested values out, for example, to get the values of rows/text, use syntax like the following:
for (NSDictionary *myKey in keys)
{
NSLog(#"rows/text --> %#", [[myKey objectForKey:#"rows"] objectForKey:#"text"]);
}
That should do it. My syntax might not be perfect there, but you get the idea.
Andy
Related
My brain is fried! I can't think.
i am new to iphone programming
am doing json parsing ....in that am storeing data from json to nsdictionary but .......
I want to add all nsdictionary float values from the dictionary to the array. This is what I am doing right now.As code below:
- (void)connectionDidFinishLoading:(NSURLConnection *)connection
{
[connection release];
NSString *responseString = [[NSString alloc] initWithData:responseData encoding:NSUTF8StringEncoding];
self.responseData = nil;
dict = [responseString JSONValue];
NSMutableArray *array = [NSMutableArray array];
for (NSString *key in [dict allKeys])
{
array = [dict objectForKey:key];
// array return float values but
[array addObject:array ]; // geting carsh dude to array return float values like 120.01
}
Please guide me i am not getting a part where i am doing a mistake.
Thanks in advance.
Your app is crashing because you are adding data to NSArray , this is static array, you can not add value at run time, so just Make NSMutableArray and add your data in NSMutableArray.
Your code is broken in a couple of ways.
This line assigns the array pointer to the object in the dictionary:
array = [dict objectForKey:key];
Then you are trying to add the array to itself, which does not make sense. But worse, since array does no longer point to your NSMutableArray you cannot even call that method.
[array addObject:array ];
You probably wanted to do something like this:
for (NSString *key in [dict allKeys])
{
id value = [dict objectForKey:key];
[array addObject:value];
}
i have searched a lot but not able two sort my array a/c to requirement
i used this code:
[array1 sortArrayUsingSelector:#selector(caseInsensitiveCompare:) withPairedMutableArrays:arrForName, arrForAddress, nil];
thanks
On the NSArray Class Reference there isn't a - sortArrayUsingSelector:withPairedMutableArrays: method. Neither on the NSMutableArray Class Reference. If you want, you can use other methods like the NSMutableArray sortUsingSelector: method.
Put the two arrays into a dictionary as keys and values
NSDictionary *dictionary = [NSDictionary dictionaryWithObjects:arrForAddress forKeys:arrForName];
// Sort the first array
NSArray *sortedFirstArray = [[dictionary allKeys] sortedArrayUsingSelector:#selector(compare:)];
// Sort the second array based on the sorted first array
arrForAddress=[[NSMutableArray alloc]init ];
NSArray *sortedSecondArray = [dictionary objectsForKeys:sortedFirstArray notFoundMarker:[NSNull null]];
// arrForAddress = [dictionary objectsForKeys:sortedFirstArray notFoundMarker:[NSNull null]];
[arrForAddress addObjectsFromArray:sortedSecondArray];
NSLog(#"arrangesort......%#",arrForAddress);
I have and array of many strings.
I wan't to sort them into a dictionary, so all strings starting the same letter go into one array and then the array becomes the value for a key; the key would be the letter with which all the words in it's value's array begin.
Example
Key = "A" >> Value = "array = apple, animal, alphabet, abc ..."
Key = "B" >> Value = "array = bat, ball, banana ..."
How can I do that?
Thanks a lot in advance!
NSArray *list = [NSArray arrayWithObjects:#"apple, animal, bat, ball", nil];
NSMutableDictionary *dict = [NSMutableDictionary dictionary];
for (NSString *word in list) {
NSString *firstLetter = [[word substringToIndex:1] uppercaseString];
NSMutableArray *letterList = [dict objectForKey:firstLetter];
if (!letterList) {
letterList = [NSMutableArray array];
[dict setObject:letterList forKey:firstLetter];
}
[letterList addObject:word];
}
NSLog(#"%#", dict);
You can achieve what you want through the following steps:
Create an empty but mutable dictionary.
Get the first character.
If a key for that character does not exist, create it.
Add the word to the value of the key (should be an NSMutableArray).
Repeat step #2 for all keys.
Here is the Objective-C code for these steps. Note that I am assuming that you want the keys to be case insensitive.
// create our dummy dataset
NSArray * wordArray = [NSArray arrayWithObjects:#"Apple",
#"Pickle", #"Monkey", #"Taco",
#"arsenal", #"punch", #"twitch",
#"mushy", nil];
// setup a dictionary
NSMutableDictionary * wordDictionary = [[NSMutableDictionary alloc] init];
for (NSString * word in wordArray) {
// remove uppercaseString if you wish to keys case sensitive.
NSString * letter = [[word substringWithRange:NSMakeRange(0, 1)] uppercaseString];
NSMutableArray * array = [wordDictionary objectForKey:letter];
if (!array) {
// the key doesn't exist, so we will create it.
[wordDictionary setObject:(array = [NSMutableArray array]) forKey:letter];
}
[array addObject:word];
}
NSLog(#"Word dictionary: %#", wordDictionary);
Take a look at this topic, they solves almost the same problem as you — filtering NSArray into a new NSArray in objective-c Let me know if it does not help so I will write for you one more code sample.
Use this to sort the contents of array in alphabetical order, further you design to the requirement
[keywordListArr sortUsingSelector:#selector(localizedCaseInsensitiveCompare:)];
I just wrote this sample. It looks simple and does what you need.
NSArray *names = [NSArray arrayWithObjects:#"Anna", #"Antony", #"Jack", #"John", #"Nikita", #"Mark", #"Matthew", nil];
NSString *alphabet = #"ABCDEFGHIJKLMNOPQRSTUWXYZ";
NSMutableDictionary *sortedNames = [NSMutableDictionary dictionary];
for(int characterIndex = 0; characterIndex < 25; characterIndex++) {
NSString *alphabetCharacter = [alphabet substringWithRange:NSMakeRange(characterIndex, 1)];
NSArray *filteredNames = [names filteredArrayUsingPredicate:[NSPredicate predicateWithFormat:#"SELF BEGINSWITH[C] %#", alphabetCharacter]];
[sortedNames setObject:filteredNames forKey:alphabetCharacter];
}
//Just for testing purposes let's take a look into our sorted data
for(NSString *key in sortedNames) {
for(NSString *value in [sortedNames valueForKey:key]) {
NSLog(#"%#:%#", key, value);
}
}
i m parsing a json url using SBJSON and everything works fine. the problem is if m to parse the tag "title" or bascially any other tag and store it in an array named story.. i m able to get only the last value containing the tag and not the entire list of values stored in the array named story below is the code..
- (void)viewDidLoad {
[super viewDidLoad];
jsonurl=[NSURL URLWithString:#"http://www.1040communications.net/sheeba/stepheni/iphone/stephen.json"];
jsonData=[[NSString alloc]initWithContentsOfURL:jsonurl];
jsonArray = [jsonData JSONValue];
items = [jsonArray objectForKey:#"items"];
for (NSDictionary *item in items )
{
story = [NSMutableArray array];
description1 = [NSMutableArray array];
[story addObject:[item objectForKey:#"title"]];
[description1 addObject:[item objectForKey:#"description"]];
}
NSLog(#"booom:%#",story);}
The story and description1 should be declared before the loop starts.
This line should be outside the for loop
story = [NSMutableArray array];
The NSMutableArray is being created for every item in your dictionary and hence you are getting the last value only. So you need to create the dictionary before you enter the for loop.
I want to parse a JSON file in my iphone app. The problem is i can parse simple json files but i am confused how to do parsing on following type of json:
[{"123":
[{ "item_id":"222",
"image_count":"2",
"image_filetype":".jpg",
"image_url":"http:\/\/someurl.jpg",
},
{"item_id":"333",
"image_count":"2",
"image_filetype":".jpg",
"image_url":"http:\/\/someurl.jpg",
}]
}]
Can some on help me how to extract all the img_urls for "123".
Thank you.
NSString *jsonString = …;
// The top-level object is an array
NSArray *array = [jsonString JSONValue];
// The first element in the array is an object containing a name-value
// pair for the key/name "123". The value is itself an array
NSArray *itemsIn123 = [[array objectAtIndex:0] objectForKey:#"123"];
// Use Key-Value Coding to get an array of all values for the key
// image_url
NSArray *imgurls = [itemsIn123 valueForKey:#"image_url"];
Edit based on comments:
Since the top-level array may consist of several objects, each object having a single name-value pair with unknown name, you need to manually iterate over the top-level array:
NSString *jsonString = …;
NSMutableArray *imgurls = [NSMutableArray array];
// The top-level object is an array
NSArray *array = [jsonString JSONValue];
// Each element in the top-level array is an object
for (NSDictionary *outerObject in array) {
// Iterate over all values in the object. Each (single) value is an array
for (NSArray *innerArray in [outerObject allValues]) {
[imgurls addObjectsFromArray:[innerArray valueForKey:#"image_url"]];
}
}
The value for the object "123" will be an NSArray of NSDictionaries. Each of these dictionaries has a key "image_url" for the image url.
The code will depend on which JSON parsing library you use, but the basics should be the same.
First you want to take the key values like 123,112,189 so we will take the keys into an array
say the structure like [ Web { 123 {image url} 112 {image url} 189 {image url} ]
so
NSString *responseString = [[NSString alloc] initWithData:responseData encoding:NSUTF8StringEncoding];
SBJSON *jsonParser = [SBJSON alloc]init];
NSMutableArray *yourArray1 = [jsonParser objectWithString:responseString]copy]]autorelease;
ufArray = [[yourArray1 valueForKey:#"web"] copy];
for (NSString *s in ufArray) {
[keys addObject:[NSDictionary dictionaryWithObjectsAndKeys:s,#"keys",nil]];
}
NSLOG(#"keys :%#",keys);
// this will contain 112,123,114 etc values
initialize a NSMutableArray
finalArray = [NSMutableArray alloc]init];
for (int i = 0; i < [ufArray count]; i ++) {
yourArray1 = [ufArray valueForKey:[[keys objectAtIndex:i]valueForKey:#"keys"]];
// [keys object at indes:i] - > 123 val / next loop 112 array like that
[finalArray addObject:yourArray1];
}
[jsonParser release];
jsonParser = nil;
Hope this helps!
Well if that array was called jArray
var img_urls = [];
var jL = jArray[0][123].length;
var img_urls = [];
for(var i = 0; i < jL; i++){
img_urls[i] = jArray[0][123][i].image_url;
}
//display in console:
console.log(img_urls);
demo: http://jsfiddle.net/maniator/Vx3hu/4/
I've never used JSON before, never used iPhone before, never used Xcode before...but I would think its something along along the lines of...
//object and image for item ID 222
123: item_id(222).image_url("some_url")
or the second and following items
//hi
123: item_id(333).image_url("some_url")
However something better would be when you can extract the image without the URL by using the item ID and an image ID, so when calling the object 123, you can specify the item id and the image id, which would then output all the information you require. For instance the count, file type and the image could all be displayed.
123: item_id(222).image_id(222)
Is the data file SQL or XML? XML is usually faster! So read up on nodes.
Hope that helps.
DL.