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];
}
Related
I have this JSON.
{
"cnt": 1,
"list": [
{
"object1": [
{
"subobject1": "value1",
"subobject2": "value2",
"subobject3": "value3"
}
],
"object2": {
"subobject1": value1,
"subobject1": value2,
"subobject1": value3
}
}
]
}
I can't get data from the first object. I receive an error
-[__NSArrayM objectForKeyedSubscript:]: unrecognized selector sent to instance 0x7fa281f82520
*** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[__NSArrayM objectForKeyedSubscript:]: unrecognized selector sent to instance 0x7fa281f82520'
For the other object I get the data and I can see it in the NSLOG, but can't understand what's the problem with the first one and why the app is crashing.
This is how I parse the json in the DataModel
NSError *deserializationError;
NSMutableDictionary *json = [NSJSONSerialization JSONObjectWithData:data options: NSJSONReadingMutableContainers error: &deserializationError];
NSArray * responseArr = json[#"list"];
NSMutableArray *result = [[NSMutableArray alloc] init];
if(responseArr && [responseArr isKindOfClass:[NSArray class]]) {
for(NSDictionary *cDictionary in responseArr) {
DAObject *cty = [[DAObject alloc] initWithDictionary:ctyDictionary];
if(cty) {
[result addObject:cty];
}
}
}
then In the Object .m file
DAServiceObject *object1 = [[DAServiceObject alloc] initWithDictionary:dictionary[#"object1"]];
self.value1 = object1.value1;
self.value2 = object1.value2;
and the app crashes.
You misinterpreted the data structure: "list" contains an array with only one item, i.e. a dictionary. This dictionary contains an array for each key (e.g. "item1"), again with only one item (again a dictionary).
edit
// ...
if(responseArr && [responseArr isKindOfClass:[NSArray class]]) {
NSDictionary *content = responseArr[0];
for (NSSString *key in [content allKeys]) {
NSDictionary *a = content[key][0];
// ...
}
}
Your JSON data is not an array. It is a dictionary. It's a dictionary with one key "cnt" and one key "list". The object under key "list" is an array.
I seem to be having a small issue with the parsing through a nested JSON result. The following code works perfectly if the JSON is not nested. I'm a littler perplexed on how to proceed as every attempted (through examples of others) have failed.
So, to test this I'm using the following API from https://developer.worldweatheronline.com/page/explorer-free
I simply would like to get my current temperature (temp_c).
Below is the code calling the service. Note that I have an NSObject that will fill the data, but of course I can't seem to get to that stage. Also it is an NSMutableArray throughout. Again, I don't think that is the issue but provides context.
-(void)retrieveLocalWeatherService {
NSURL *url = [NSURL URLWithString:getLocalWeather];
NSData *data = [NSData dataWithContentsOfURL:url];
jsonArray = [NSJSONSerialization JSONObjectWithData:data options:kNilOptions error:nil];
//set up array and json call
weatherArray = [[NSMutableArray alloc]init];
//Loop through the JSON array
for (int i = 0; i< jsonArray.count; i++)
{
//create our object
NSString *nTemp = [[jsonArray objectAtIndex:i]objectForKey:#"temp_C"];
NSString *nPressure = [[jsonArray objectAtIndex:i]objectForKey:#"pressure"];
NSString *nHumidity = [[jsonArray objectAtIndex:i]objectForKey:#"humidity"];
//Add the object to our animal array
[weatherArray addObject:[[LocalWeather alloc]initWithtemp:(nTemp) andpressure:nPressure andhumidity:nHumidity]];
}
Here is the JSON response.
{
"data": {
"current_condition": [
{
"cloudcover": "75",
"FeelsLikeC": "31",
"FeelsLikeF": "88",
"humidity": "70",
"observation_time": "05:15 AM",
"precipMM": "0.0",
"pressure": "1011",
"temp_C": "28",
"temp_F": "82",
"visibility": "10",
"weatherCode": "116",
"weatherDesc": [
{
"value": "Partly Cloudy"
}
],
"weatherIconUrl": [
{
"value": "http://cdn.worldweatheronline.net/images/wsymbols01_png_64/wsymbol_0002_sunny_intervals.png"
}
],
"winddir16Point": "N",
"winddirDegree": "10",
"windspeedKmph": "41",
"windspeedMiles": "26"
}
],
"request": [
{
"query": "Brisbane, Australia",
"type": "City"
}
],
I cut off the JSON service as it goes for miles, so where am I going wrong? I believe its somewhere within "for-loop" but am unsure where. I know its major node is "data" and then sub-node is "current_condition". Should I be digging through the JSON results? If what is the best approach.
BTW, I'm getting a response from the server with the entire JSON result..clearly a parsing issue on my part.
Thanks in advance!
please be kind i'm a newbie.
You are parsing your JSON data in wrong way, you are parsing JSON directly to Array but as per your JSON format your JSON will return an NSDictionary not NSArray.
-(void)retrieveLocalWeatherService {
NSURL *url = [NSURL URLWithString:getLocalWeather];
NSData *data = [NSData dataWithContentsOfURL:url];
NSDictionary *weatherJson = [NSJSONSerialization JSONObjectWithData:data options:kNilOptions error:nil];
NSArray *currentConditionArray = [weatherJson valueForKeyPath:#"Data.current_condition"];
//set up array and json call
weatherArray = [[NSMutableArray alloc]init];
//Loop through the JSON array
for (NSDictionary *item in currentConditionArray)
{
//create our object
NSString *nTemp = [item objectForKey:#"temp_C"];
NSString *nPressure = [item objectForKey:#"pressure"];
NSString *nHumidity = [item objectForKey:#"humidity"];
//Add the object to our animal array
[weatherArray addObject:[[LocalWeather alloc]initWithtemp:(nTemp) andpressure:nPressure andhumidity:nHumidity]];
}
}
We have a JSON file in the server. We were able to retrieve the JSON file, but apparently we could not get the items in the nested JSON.
Here is the snippet of our code:
- (void)onSuccess:(WLResponse *)response{
NSLog(#"Connection Success: %#",response);
NSString *resultText;
if ([response responseText] != nil) {
resultText = [response responseText];
NSDictionary *allData = [response getResponseJson];
NSDictionary *resultData = allData[#"result"];
...
}
}
Below is our JSON file structure:
{"contacts":[
{
"name":"name 1",
"address":"address 1"
},
{
"name":"name 2",
"address":"address 2"
},
{
"name":"name 3",
"address":"address 3"
}
]}
You can use valueForKeyPath: after you have an NSDictionary on the client.
For example, pseudocode:
NSArray* contacts = [allData valueForKeyPath:#"result.contacts"];
NSString* firstContactName = contacts[0][#"name"];
I assume your NSDictionary referenced by allData has the contacts NSArray in the results.contacts key path. If that's not the case, modify according to the structure of your NSDictionary.
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"]]];
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"]);
}