Trouble iterating through Array - ios

How's it going folks---I'm having trouble iterating through an array in xcode--hoping someone can point me in the right direction..here's my response json response
NSString *str=#"jsonUrlremoved";
NSURL *url=[NSURL URLWithString:str];
NSData *data=[NSData dataWithContentsOfURL:url];
NSError *error=nil;
id response=[NSJSONSerialization JSONObjectWithData:data options:
NSJSONReadingMutableContainers error:&error];
{
   "item":{
      "1":{
         "title":"Item Title",
         "description":"long description",
         "date":" March 01, 2014"
      },
      "2":{
         "title":"Item Title",
         "description":"long description",
         "date":" March 01, 2014"
      },
      "3":{
         "title":"Item Title",
         "description":"long description",
         "date":" March 01, 2014"
      }
   }
}
I've tried converting to nsdictionary as well as nsobject and nsarray with no luck (cause I'm a noob)
NSDictionary *results = [response objectForKey:#"item"];
for (NSDictionary *result in results) {
NSString *image = [result objectForKey:#"image"];
NSString *desc = [result objectForKey:#"description"];
NSString *title = [result objectForKey:#"title"];
}
The app either crashes or returns null---any guidance is appreciated

For openers, your data doesn't have a value for the key #"image".
But beyond that, when you get the object for #"item", what it will return you is an array of three more dictionaries, with keys #"1", #"2", and #"3". Do a get on those keys, and you should then be able to get the subfields.
Do a 'po result' in the debugger when you breakpoint at the beginning of your 'for' loop. It will print out the type of the object you've got (whether it's an NSDictionary or NSArray) and change your code to agree to what's in your data structure.

Your JSON Object does not contain an array. So Iterating through it is out of question. You essentially have nested Dictionaries. If you need to do some Array stuff, I'd consider changing your JSON's Item object's value to an Array "[]" instead of a Dictionary "{}". That way, you don't even have to deal with indices in your JSON object. You get them for free.
The "Corrected" JSON object would look something like this:
{
"item":[
{
"title":"Item Title",
"description":"long description",
"date":" March 01, 2014"
},
{
"title":"Item Title",
"description":"long description",
"date":" March 01, 2014"
},
{
"title":"Item Title",
"description":"long description",
"date":" March 01, 2014"
}
]
}

One way of doing this if you dont't want to restructure your JSON can be as follows, it's just a way around not to be prescribed :P
NSDictionary *results = [response objectForKey:#"item"];
NSString *image = [[result objectForKey:#"1"]objectForKey:#"image"] ;
NSString *desc = [[result objectForKey:#"1"]objectForKey:#"description"];
NSString *title = [[result objectForKey:#"1"]objectForKey:#"title"];
and similarly for the rest of the objects

Related

How assign value to a JSON string?

I get this JSON object from my web service
0: {
Username: "John"
Password: "12345"
Position: "Admin"
Job: "Developer"
ResourceJobId: 1
}
When I try to assign a value, for example, to Username JSON string, I get a semantic error:
id obj = [NSJSONSerialization JSONObjectWithData:data
options:NSJSONReadingAllowFragments
error:&error];
for (NSDictionary *dictionary in array) {
NSString *usernameString = #"";
//this line of code gives me an error: Expression is not assignable
[dictionary objectForKey:#"Username"] = usernameString ;
I know how get the JSON object with NSJSONSerialization class, but my target is how assign the value #"" to the JSON object.
So how can I assign the value #"" to the Username JSON string?
While you are trying to fetched dictionary from array. it is not mutable dictionary so you need to created NSMutableDictionary while fetching data from Array. following code will help you to change username.
for (NSMutableDictionary *dictionary in array)
{
NSMutableDictionary* dictTemp = [NSMutableDictionary dictionaryWithDictionary:dictionary];
[dictTemp setObject:usernameString forKey#"Username"];
[_arrayList replaceObjectAtIndex:index withObject:dictTemp];
}
Well your assignment operation is written wrong, it should be indeed like this:
If you need to get value from dictionary
usernameString = [dictionary objectForKey:#"Username"];
If you want to set a value to your dictionary, first of all your dictionary should be NSMutableDictionary
[dictionary setObject:usernameString forKey:#"Username"];
NSData *data = [NSData dataWithContentsOfURL:url];
NSError *error;
id obj = [NSJSONSerialization JSONObjectWithData:data
options:NSJSONReadingAllowFragments
error:&error];
if(!error && [obj isKindOfClass:[NSArray class]]){
NSArray *array = (NSArray *)obj;
Booking *booking = nil;
for (NSMutableDictionary *dictionary in array) {
NSString *usernameString = #"";
//this line of code gives me an error: Expression is not assignable
[dictionary objectForKey:#"Username"] = usernameString;
Yes, is a compiler error
You need to have a mutabledictionary inorder to change the value. Try this
for (NSDictionary *dictionary in array) {
NSMutableDictionary *mutableDictionary = [NSMutableDictionary dictionaryWithDictionary:dictionary];
NSString *usernameString = #"";
[mutableDictionary setValue:#"" forKey:usernameString];
}
Even the answers are correct, I want to add that you do not have to do this your own. NSJSONSerialization already has a solution for that. Simply pass as options one of these:
NSJSONReadingMutableContainers = (1UL << 0),
NSJSONReadingMutableLeaves = (1UL << 1),
when reading the JSON.

iOS: JSON displays dictionary out of order. How to present a reordering?

Say we have the following dictionary:
dict = [NSDictionary dictionaryWithObjectsAndKeys:
[NSNumber numberWithInt:currentItem], #"item number",
[NSNumber numberWithInt:([[item valueForKey:#"section"] intValue]+1)], #"section number",
currentDate, #"date of item",
[NSNumber numberWithDouble:timeDifference], #"time difference in millis",
nil];
Then I get the following output:
{
"time difference in millis" : 5.220093071460724,
"section number" : 1,
"date of item" : "28/04/2014 15:56:54,234",
"item number" : 3
}
I use the following code to convert the dictionary to JSON:
NSData *jsonData = [NSJSONSerialization dataWithJSONObject:dict options:NSJSONWritingPrettyPrinted error:nil];
NSString *jsonString = [[NSString alloc] initWithBytes:[jsonData bytes] length:[jsonData length] encoding:NSUTF8StringEncoding];
jsonString = [jsonString stringByReplacingOccurrencesOfString:#"\\" withString:#""];
How can I manipulate the order in which the JSON string shows its keys. For example, I would like to have:
{
"item number" : 3,
"section number" : 1,
"date of item" : "28/04/2014 15:56:54,234",
"time difference in millis" : 5.220093071460724
}
or something else. The point is that I want control over this process. How do I get it? My first thought was writing a parser that shows the ordering in the way that I want.
Here are similar questions, but my emphasis is on manipulating the order instead of just recreating the order in which I put it from the dictionary.
JSON format: getting output in the correct order
Need JSON document that is generated to be in same order as objects inserted in NSMutableDictionary in iOS
NSDictionary is not ordered by definition.
Easiest will be to wrap everything into NSArray if you want to have same order.
To restate the question: how to take an inherently unordered input, produce a string who's specification is inherently unordered, but control the ordering of that string.
Reformatting the dictionary as an array would let you control input ordering, but produce a different output format.
The only reason I can imagine wanting to do this is if wish to use the JSON string not as JSON, but just as a string. The question can then be restated as just lexically reformatting the string.
How general purpose must it be? Can we assume that the JSON has simple, scalar values? Then...
- (NSString *)reorderJSON:(NSString *)json keys:(NSArray *)orderedKeys {
NSArray *splitJson = [json componentsSeparatedByString:#","];
NSMutableArray *splitResult = [NSMutableArray array];
for (NSString *key in orderedKeys) {
for (NSString *splitPair in splitJson) {
if ([self jsonPair:splitPair hasKey:key]) {
NSString *trimmedSplitPair = [splitPair stringByTrimmingCharactersInSet:[NSCharacterSet characterSetWithCharactersInString:#"{}"]];
[splitResult addObject:trimmedSplitPair];
}
}
}
NSString *joinedResult = [splitResult componentsJoinedByString:#","];
return [NSString stringWithFormat:#"{%#\n}", joinedResult];
}
- (BOOL)jsonPair:(NSString *)pair hasKey:(NSString *)key {
// pair should begin with double quote delimited key
NSString *trimmedPair = [pair stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceCharacterSet]];
NSArray *splitPair = [trimmedPair componentsSeparatedByString:#"\""];
return [splitPair[1] isEqualToString:key];
}
Call it like this:
- (void)testJson {
NSDictionary *d = #{ #"time difference in millis": #5.220093071460724,
#"section number": #1,
#"date of item" : #"28/04/2014 15:56:54,234",
#"item number": #3};
NSData *jsonData = [NSJSONSerialization dataWithJSONObject:d options:NSJSONWritingPrettyPrinted error:nil];
NSString *jsonString = [[NSString alloc] initWithBytes:[jsonData bytes] length:[jsonData length] encoding:NSUTF8StringEncoding];
NSArray *orderedKeys = #[ #"item number", #"section number", #"date of item", #"time difference in millis"];
NSString *result = [self reorderJSON:jsonString keys:orderedKeys];
NSLog(#"%#", result);
}
You shouldn't want that. Dictionaries have no order and writing some code that uses the order will just lead to problems in the future.
That said, if you want to, you can write your own code to generate the JSON string from your (ordered) array of keys and dictionary of values.

Json Response parsing

I got json reponse in the following way...i have tried to parse in many ways all went ruin.
dic:
(
{
events = {
id = 1;
name = "Event One";
};
},
{
events = {
id = 2;
name = "Test 2";
};
},
{
events = {
id = 12;
name = "vivek 11";
};
},
)
NSDictionary *jsonDictionaryResponse = [response JSONValue];
NSString *name=[[[jsonDictionaryResponse objectForKey:#"events"]objectAtIndex:0]valueForKey:#"name"];
json response:
Login response :[{"events":{"id":"1","name":" Event
One"}},{"events":{"id":"2","name":"Test
2"}},{"events":{"id":"12","name":"vivek
11"}},{"events":{"id":"13","name":"Baby's Day
out"}},{"events":{"id":"15","name":"Childrens
Day"}},{"events":{"id":"16","name":"event
two"}},{"events":{"id":"17","name":"Test
Creattion"}},{"events":{"id":"29","name":"Susan
Test"}},{"events":{"id":"30","name":"Summer
Holidays"}},{"events":{"id":"38","name":"Event
7"}},{"events":{"id":"69","name":"vivek event for
tests"}},{"events":{"id":"102","name":"chinees food mela"}}]
first transform your response string to NSData. then try this:
NSError *error;
NSArray *jSONArray = [NSJSONSerialization JSONObjectWithData:jsonData options:kNilOptions error:&error];
for (NSDictionary *dict in jSONArray) {
NSDictionary *event = [dict objectForKey=#"events"];
NSString *name = [event objectForKey:#"name"];
....
}
The easiest way to understand a JSON object in Objective-C is to understand how it breaks things up into Arrays and Dictionaries. Every time you see a "[" think Array. Every time you see a "{" think Dictionary.
An Array can have Dictionary or other Array objects as part of the collection and a Dictionary can have Array or more Dictionary objects which can contain more Arrays or Dictionaries.
If you remember that "[ ]" means Array and "{ }" means Dictionary, you will know JSON in Objective-C.
Check that result coming as JSON. it is not aDictionary check it
here
PLease find the code here
NSArray *jsonArrayResponse = [response JSONValue];
NSDictionary *firstDic = [jsonArrayResponse objectAtIndex:0];
NSDictionary *secondDic = [firstDic objectForKey:#"events"];
NSLog(#"The values in the events dictioanry is %# ",[secondDic allValues]);
NSString *stringNAme = [secondDic objectForKey:#"id"];

ios development - How to do JSON parser?

I'm new to ios development. Now I get a JSON file from server.
I use NSDictionary to get objects. When I debug, I could get "name", "address" values.
But I don't know how can I get all "dish" elements from "recommendation" Object? In java development, I know recommendation is an object, and "dish" is an array element. But I don't know what happen in ios.
{
"results": [
{
"name": "ollise",
"address": "columbia university",
"geo": [
{
"coordinates": 40
},
{
"coordinates": 70
}
],
"logo": "http:\/\/a0.twimg.com\/profile_images\/3159758591\/1548f0b16181c0ea890c71b3a55653f7_normal.jpeg",
"recommendation": [
{
"dish": "dish1"
},
{
"dish": "dish2"
}
],
}
]
}
By the way, in JSON, I store URL of an image in "logo", but I cannot get the value when debugging. Should I use some special format?
[Restaurant setname:[Dict objectForKey:#"name"]] // I could get name
[Restaurant setlogo:[Dict objectForKey:#"logo"]] // I can get nothing!
This is the way to do it
NSDictionary *response = [NSJSONSerialization JSONObjectWithData:yourData options:NSJSONReadingMutableLeaves error:nil];
NSDictionary *results = [[response objectForKey:#"results"] objectAtIndex:0];
NSString *name = [response objectForKey:#"name"];
//... get other objects
NSArray *recommendation = [results objectForKey:#"recommendation"];
NSDictionary *recommendation1 = [recommendation objectAtIndex:0];
NSDictionary *recommendation2 = [recommendation objectAtIndex:1];
NSString *dish = [recommendation1 objectForKey#"dish"];
NSString *dish1 = [recommendation2 objectForKey#"dish"];
[Restaurant setname:name];
NSString *logo = [results objectForKey:#"logo"];
[Restaurant setlogo:logo];
The results is the same dictionary as the one in the JSON. Treat anything with braces ({}) as an NSDictionary and brackets ([]) as an NSArray. dish is not an array element, it is a key in a dictionary that is an array element.

Understand and use this JSON data in iOS

I created a web service which returns JSON or so I think. The data returned look like this:
{"invoice":{"id":44,"number":42,"amount":1139.99,"checkoutStarted":true,"checkoutCompleted":true}}
To me, that looks like valid JSON.
Using native JSON serializer in iOS5, I take the data and capture it as a NSDictionary.
NSError *error;
NSDictionary *json = [NSJSONSerialization JSONObjectWithData:[request responseData] options:kNilOptions error:&error];
NSLog(#"json count: %i, key: %#, value: %#", [json count], [json allKeys], [json allValues]);
The output of the log is:
json count: 1, key: (
invoice
), value: (
{
amount = "1139.99";
checkoutCompleted = 1;
checkoutStarted = 1;
id = 44;
number = 42;
}
)
So, it looks to me that the JSON data has a NSString key "invoice" and its value is NSArray ({amount = ..., check...})
So, I convert the values to NSArray:
NSArray *latestInvoice = [json objectForKey:#"invoice"];
But, when stepping through, it says that latestInvoice is not a CFArray. if I print out the values inside the array:
for (id data in latestInvoice) {
NSLog(#"data is %#", data);
}
The result is:
data is id
data is checkoutStarted
data is ..
I don't understand why it only return the "id" instead of "id = 44". If I set the JSON data to NSDictionary, I know the key is NSString but what is the value? Is it NSArray or something else?
This is the tutorial that I read:
http://www.raywenderlich.com/5492/working-with-json-in-ios-5
Edit: From the answer, it seems like the "value" of the NSDictionary *json is another NSDictionary. I assume it was NSArray or NSString which is wrong. In other words, [K,V] for NSDictionary *json = [#"invoice", NSDictionary]
The problem is this:
NSArray *latestInvoice = [json objectForKey:#"invoice"];
In actual fact, it should be:
NSDictionary *latestInvoice = [json objectForKey:#"invoice"];
...because what you have is a dictionary, not an array.
Wow, native JSON parser, didn't even notice it was introduced.
NSArray *latestInvoice = [json objectForKey:#"invoice"];
This is actually a NSDictionary, not a NSArray. Arrays wont have keys. You seem capable from here.
Here I think You have to take to nsdictionary like this
NSData* data = [NSData dataWithContentsOfURL: jsonURL];
NSDictionary *office = [NSJSONSerialization JSONObjectWithData:data options:kNilOptions error:nil];
NSDictionary *invoice = [office objectForKey:#"invoice"];

Resources