Xcode Json returns nil in array - objective-c

I don't see what i am doing wrong here but i can't get the JSON back good in the array..
this is what JSON returns:
(html)
"Response": {
"objecten": {
"object": [
{
"id": "12345
(Xcode)
NSArray *array = [dictionary objectForKey:#"object"];
if (array == nil) {
NSLog(#"No 'data' in array");
return;
}
i get the error because its nil, but if i fill in #"Response" instead of #"object" i get an array back with data.
Then i loop thrue it
for (NSDictionary *resultDict in array) {
NSLog(#"%#",resultDict);
and it has only "objecten" nothing more...
So what am i doing wrong ?

It's just a tree of objects. Try:
NSArray * arr =[[[dictionary objectForKey:#"Response"] objectForKey:#"objecten"] objectForKey:#"object"]]];

Related

How to check if NSDictionary is null and read the JSON value in objective c

I want to check if NSDictionary is NULL or not and read the JSON values.
Here is my code for checking if NSDictionary is null :
if ([dataDict objectForKey:#"messages"]!= NULL) {
NSLog(#"not null");
}
else
{
NSLog(#"null");
}
When I print the value for [dataDict objectForKey:#"messages"] it's: messages = "<null>"
I want to read the JSON value "message": "Not valid." if messages is not null :
"messages": {
"items": [
{
"message": "Not valid."
}
]
}
If you see the output "<null>" then this means the value is an instance of NSNull. So you need to check for that as well.
I would update your code as follows:
id message = dataDict[#"messages"];
if (message == nil || message == [NSNull null]) {
NSLog("null");
} else {
NSLog("not null");
if ([message isKindOfClass:[NSDictionary class]]) {
NSDictionary *dict = (NSDictionary *)message;
NSArray *items = dict[#"items"];
if (items.count > 0) {
NSString *message = items[0][#"message"];
NSLog(#"Message: %#", message);
}
}
}

Iterate through JSON array (App Crashing)

I am trying to iterate trough a JSON array to get both the item key and value.
This is my JSON array:
{
"ClientData": [{
"Name": "Michael"
}, {
"Last": "Ortiz"
}, {
"Phone": "5555555555"
}, {
"email": "test#gmail.com"
}],
"ClientAccess": [{
"T-Shirt": "YES"
}, {
"Meals": "NO"
}, {
"VIP": "YES"
}, {
"Registration Completed": "Pending"
}]
}
Now, I am trying to iterate through the "ClientData" array, but for some reason the app is crashing with this exception:
*** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[__NSCFString objectForKey:]: unrecognized selector sent to instance
This is the code I am using to iterate through the JSON array:
NSDictionary* object = [NSJSONSerialization JSONObjectWithData:JSONData options:kNilOptions error:nil];
// Client Profile Data
NSDictionary *clientDataDict = [object objectForKey:#"ClientData"];
for (id item in clientDataDict)
{
[JSONUserData addObject:[clientDataDict objectForKey:item]];
}
This code was working fine when I didn't have each item on the JSON array placed inside an array. I did this to keep a consecutive order on the array.
Can someone give me any pointers on what the problem is?
Thank you!
ClientData is an array – represented by the square brackets [] – containing dictionaries with one key/value pair respectively (a quite cumbersome structure).
NSDictionary* object = [NSJSONSerialization JSONObjectWithData:JSONData options:kNilOptions error:nil];
// Client Profile Data
NSArray *clientDataArray = [object objectForKey:#"ClientData"];
for (NSDictionary *dict in clientDataArray) {
for (NSString *key in dict) {
[JSONUserData addObject:[dict objectForKey:key]];
}
}
According to your JSON strings, it looks like that ClientData pairs with an array and each item in array is a dictionary. Therefore, revised codes will look like:
NSMutableDictionary *mDict = [NSMutableDictionary new];
NSArray *array = [object objectForKey:#"ClientData"];
for (NSDictionary *item in array) {
[mDict addEntriesFromDictionary:item];
}

NSdictionary returns error when 1 returns

Everything works when i get more then 1 objects back but when its only 1 it reacts weird, i can't find the solution for it.
First i set everything in an array:
NSArray *array = [[[dictionary objectForKey:#"Response"] objectForKey:#"objecten"] objectForKey:#"object"];
if (array == nil) {
NSLog(#"Expected 'results' array");
return;
}
then i use a for loop on a dictionary
for (NSDictionary *resultDict in array) {
SearchResult *searchResult;
NSString *wrapperType = [resultDict objectForKey:#"type"];
if ([wrapperType isEqualToString:#"rent"])
{
searchResult = [self parseHuur:resultDict];
}
if (searchResult != nil) {
[searchResults addObject:searchResult];
}}
So when results get back more then 1 everything works great, but when just one gets back i get:
-[__NSCFString objectForKey:]: unrecognized selector sent to instance 0x6e52c30
*** Terminating app due to uncaught exception
'NSInvalidArgumentException', reason: '-[__NSCFString objectForKey:]:
unrecognized selector sent to instance 0x6e52c30'
it points to this line:
NSString *wrapperType = [resultDict objectForKey:#"type"];
I really don't get it...
i check the results of the api in the browser with the same link and it really returns 1 object, but when i log the resultDict (NSlog it) i get only one answer: id instead of the whole object with all parameters (i don't know if this is the right name for it)
how can that be ?
Some of your results aren't full NSDictionaries but rather just NSStrings. You can check for this:
for (id result in array) {
if ([result isKindOfClass:[NSDictionary class]]) {
NSDictionary *resultDict = (NSDictionary *)result;
...
As per your comments, array is not always an array as you have mentioned. It could be an array or dictionary. So try this,
id someObject = [[[dictionary objectForKey:#"Response"] objectForKey:#"objecten"] objectForKey:#"object"]; //naming it as someObject since it is not always an array
if (someObject == nil) {
NSLog(#"Expected 'results' array");
return;
}
if ([someObject isKindOfClass:[NSDictionary class]]) { //Just add this
someObject = [NSArray arrayWithObject:someObject];
}
NSArray *array = (NSArray *)someObject;//type cast to an array now
for (NSDictionary *resultDict in array) {
SearchResult *searchResult;
NSString *wrapperType = [resultDict objectForKey:#"type"];
if ([wrapperType isEqualToString:#"rent"])
{
searchResult = [self parseHuur:resultDict];
}
if (searchResult != nil) {
[searchResults addObject:searchResult];
}
}
When you use the fast enumeration for a NSDictionary, the iterating variable is from the set of keys in the dictionary not the values.
http://developer.apple.com/library/ios/#documentation/cocoa/conceptual/objectivec/Chapters/ocFastEnumeration.html
The resultDict isn't an NSDictionary hence you can't invoke objectForKey: on this object.
A better solution would be to treat resultDict as id type in the for loop, and check its class type for NSDictionary before using it.
-[__NSCFString objectForKey:]
So it's calling the objectForKey: method on an NSString. It seems that the API you're using for getting the objects follows a common idiom: it uses duck-typing/polimorphism (to use these nice OO-related words) and it returns either an array of objects if it has more than results, or a single object (and not an array of one element) when it has only one result. So, you have to use reflection (OMG, even more OO terminology!) to inspect whether the returned object is actually an array - either
id result = [dictionary objectForKey:#"Response"];
id value;
if ([result isKindOfClass:[NSDictionary class]]) {
value = [[result object objectForKey:#"objecten"] objectForKey:#"object"];
} else {
value = result;
}
or
id value;
if ([dictionary isKindOfClass:[NSDictionary class]]) {
value = [[[dictionary objectForKey:#"Result"] result object objectForKey:#"objecten"] objectForKey:#"object"];
} else {
value = dictionary;
}
Try both, whichever works should be fine.

Importing JSON objects into NSArray

Trying to parse this JSON object in objective-C and creating an NSArray with these objects.
The first value is a counter and is specific for the object. All other values are unique.
{ "myData": [
["1","1","110","dollar","8.0","2.8","0.1","11.6"],
["2","1","110","euro","4.0","3.2","1.5","4.4"],
["3","1","120","rupier","6.0","2.9","1.3","10.8"],
["4","1","120","dinero","4.0","3.3","1.5","4.4"],
["5","2","130","drahmer","8.0","2.9","1.3","11.2"],
] }
Tried this code:
NSDictionary* json = [NSJSONSerialization
JSONObjectWithData:myData
options:kNilOptions
error:&error];
NSArray *currencyInformation = [json objectForKey:#"myData"];
But the objects are not there. Though the count of the array is 5.
Each object in the array is an array itself, so:
NSDictionary* json = [NSJSONSerialization
JSONObjectWithData:myData
options:kNilOptions
error:&error];
NSArray *currencyInformation = [json objectForKey:#"myData"];
for (NSArray *info in currencyInformation) {
// Then access each "column" with [info objectAtIndex:0,1,2,3,...]
}
In this data structure you would need to access things by index e.g
for (NSArray *currency in currencyInformation) {
NSLog(#"Currency: %#", [currency objectAtIndex:3]);
}
If you want to access things by key then you would need to change your JSON to use an array of objects instead of an array of arrays. Something like this:
{
"myData": [
{
"primaryKey" : 1,
"currency" : "dollar",
<other keys + values>...
},
]
}
In which case you could now do something like:
for (NSDictionary *currency in currencyInformation) {
NSLog(#"Currency: %#", [currency valueForKey:#"currency"]);
}

How to get the object types with JSONKit

I'm trying to decoder a json file and get value type for each unknowing the atributes names or the order.
Ie.
{
"Name": "Klove",
"Altitude": "100",
"Latitude": "43.421985",
"Longitude": "-5.823897"
}
So: Name will be a NString with Klove inside. Latitude a float with 43.421985....
//File initialization
NSString *filePath = [[NSBundle mainBundle]
pathForResource:#"buildings" ofType:#"json"];
NSData *fileContent = [NSData dataWithContentsOfFile:filePath];
JSONDecoder *jsonKitDecoder = [JSONDecoder decoder];
NSDictionary *dict = [jsonKitDecoder objectWithData:fileContent];
// the party starts
for (NSDictionary *poi in dict) {
for (int i = 0; i <= [[poi allKeys]count]-1 ; i++) {
// Here i'm trying to get the object type (but never with success)
if([[poi objectForKey:[[poi allKeys]objectAtIndex:i]]
isKindOfClass:[NSNumber class]]
|| [[poi objectForKey:[[poi allKeys]objectAtIndex:i]]
isKindOfClass:[NSArray class]]
|| [[poi objectForKey:[[poi allKeys]objectAtIndex:i]]
isKindOfClass:[NSDictionary class]])
{
NSLog(#"Other kind of class detected");
// do somthing but never happens
// in fact, if i use [[poi objectForKey:[[poi allKeys]objectAtIndex:i]class]
// always is __NSCFString
}
NSLog(#"%#",[[poi allKeys]objectAtIndex:i]);
NSLog(#"%#",[poi objectForKey:[[poi allKeys]objectAtIndex:i]]);
}
}
So... I don't know how could i get the type of the object in the json dictionary. Any idea? If is possible I wouldn't like to make checks like:
if ([poi allKeys]objectAtIndex:i] isEqualToString(#"Latitude"))
[[poi objectForKey:i]floatValue];
Thanks in advance.
Ok. My fault.
If I define the JSON file like:
{
"Name": "Klove",
"Altitude": 100,
"Latitude": 43.421985,
"Longitude": -5.823897
}
instead the above format I'll get the types automatically with the JSONKit.
To get the type in my code:
[poi objectForKey:[[poi allKeys]objectAtIndex:i]]