Getting one value from JSON API in Objective-C - ios

I'm trying to get one value from JSON. JSON is located in NSString and it looks like this:
{"coord":{"lon":-122.38,"lat":37.57},"weather":[{"id":300,"main":"Drizzle","description":"Lekka mżawka","icon":"09d"}],"base":"stations","main":{"temp":304.74,"pressure":1017,"humidity":35,"temp_min":300.15,"temp_max":307.59},"visibility":16093,"wind":{"speed":6.7,"deg":250},"clouds":{"all":75},"dt":1437346641,"sys":{"type":1,"id":478,"message":0.0615,"country":"US","sunrise":1437311022,"sunset":1437362859},"id":5357155,"name":"Hillsborough","cod":200}
I'm interested in getting "temp". How should I do that?

Assuming your JSON string was stored as a NSString named JSONString:
NSError *error;
NSDictionary *keys = [NSJSONSerialization JSONObjectWithData:[JSONString dataUsingEncoding:NSUTF8StringEncoding]
options:NSJSONReadingMutableContainers
error:&error];
NSLog(#"temp = %#", keys[#"main"][#"temp"]); // temp = 304.74
To get the main sub item in weather, which is an array with multiple items, you should point out its index to tell the selector which object in the array is the one you are looking for. In this case, it's 0:
NSLog(#"weather = %#", keys[#"weather"][0][#"main"]); // weather = Drizzle

Related

Single object json parse - what am I doing wrong?

This has got to be something obvious that I am doing wrong. I have been banging my head against a wall trying to figure out what is going on. I already have this json parsing done in the android version of my app, now trying to parse this simple json in xcode and can't get it done.
NSError *myError = nil;
NSDictionary *res = [NSJSONSerialization JSONObjectWithData:self.responseData options:kNilOptions error:&myError];
NSLog([res objectForKey:#"Date"]);
This code get me the "unrecognized selector sent to instance" error.
Here is the json data and you can see Date is one of the objects:
[{"Date":"2016-06-17T22:56:33.0811255-05:00"}]
Thanks in advance for any help on this issue. I've tried to simplify this post, but if more info is needed I will try and quickly provide.
http://i.stack.imgur.com/Y5fsT.png
JSONObjectWithData is returning an array of dictionaries and not a dictionary. Your print out of the raw JSON confirms this:
[{"Date":"2016-06-17T22:56:33.0811255-05:00"}] // This is an array
However you're attempting to treat that response object like a dictionary. In doing so you're calling a dictionary method (objectForKey:) on an array. This results in a crash. Try something like this:
NSError *error = nil;
id responseObject = [NSJSONSerialization JSONObjectWithData:self.responseData options:kNilOptions error:&error];
if (error)
{
// Handle error
return;
}
NSLog(#"%#", responseObject);
if ([responseObject isKindOfClass:[NSArray class]])
{
NSArray *responseArray = (NSArray *)responseObject;
for (id item in responseArray)
{
NSLog(#"%#", item);
if ([item isKindOfClass:[NSDictionary class]])
{
NSDictionary *dictionary = (NSDictionary *)item;
NSString *dateString = [dictionary objectForKey:#"Date"];
NSLog(#"%#", dateString);
}
}
}
else
{
// responseObject is not an array...
}
I'm pretty sure this is because you should first set res as [NSDictionary]. Then pick the first element in that array and then get objectForKey: "Date". Normal JSON Data starts with a {, this starts with a [. Which means it's an array.
You can see it for yourself in the screenshot when it says #: 1 Element . THEN it says 1 key/value pair. The NSDictionary is inside an array.NSError
Try this code:
*myError = nil;
[NSDictionary] *res = [NSJSONSerialization JSONObjectWithData:self.responseData options:kNilOptions error:&myError];
if (res.count > 0) {
NSLog([res[0] objectForKey:#"Date"]);
}

IOS Dev Fetching JSON Data

I am a novice at IOS dev and i really need some help.
I want to parse (which is working) and fetch some JSON Data.
i used this tutorial for the http request and json parsing
http://www.mysamplecode.com/2013/04/ios-http-request-and-json-parsing.html
everything works fine with a 1 dimensional dictionary
but I need to be able to fetch the following JSON Data
[{"defaultGateway": "10.10.10.254", "hostname": "On", "connected": "true", "subnetMask": "255.255.255.255", "iPAddress": "10.10.10.10", "dhcpEnabled": "true"},
{"defaultGateway": "10.10.10.254", "hostname": "On", "connected": "true", "subnetMask": "255.255.255.255", "iPAddress": "10.10.10.10", "dhcpEnabled": "true"}]
after I use the following function I got the following dictionary which I really don't know how to access
NSDictionary * res = [NSJSONSerialization
JSONObjectWithData:data
options:NSJSONReadingMutableContainers
error:&error];
here is a picture of the dictionary
http://www11.pic-upload.de/09.11.14/5n4hdg3eh84q.png
How can I access for example the defaultGateway in the first dictionary?
You have a small logical error in your example. The expression [NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingMutableContainers error:&error]; returns an NSArray and not and NSDictionary. So, first you should change this part to:
NSArray *result = [NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingMutableContainers error:&error];
I know it's an array because your JSON string contains an array of two JSON objects. NSJSONSerialization will transform JSON arrays into objects of type NSArray and JSON objects into objects of type NSDictionary.
If you're not sure what your JSON contains, you can do the following:
id result = [NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingMutableContainers error:&error];
if ([result isKindOfClass:[NSArray class]]){
// do something with the array
}
else if ([result isKindOfClass:[NSDictionary class]]){
// do something with the dictionary
}
As for your question, you can access the data in an NSDictionary by providing a key, which you can do in two ways:
NSString *gateway = [dictionary objectForKey:#"defaultGateway"];
or even faster:
NSString *gateway = dictionary[#"defaultGateway"];
Coming back to your example, to access the defaultGateway from the first of your two JSON objects, you can do the following:
NSArray *result = [NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingMutableContainers error:&error]; // parse the JSON and store in array
NSDictionary *dict = result[0]; // take the first of the two JSON objects and store it in a dictionary
NSString *gateway = dictionary[#"defaultGateway"]; // retrieve the defaultGateway property

Get a single specific value from json

As you might expect, i'm fairly new to obj-C, and i'm constantly trying to build knowledge and experience. But i'm still struggling with a lot of concepts, and that includes JSON data 'catching'.
I've seen many tutorials and guides but i just can't translate them into what i need. Most of the time they layout data in arrays or get multiple values, and (of course) use different variables, which makes everything confusing and unclear to me, even though this should be stupidly simple.
I'm trying to do something very simple :
Get a single value from the open weather API, the temperature.
I'll show you my code which, according to my disgraceful knowledge, should be perfect, but apparently it doesn't work :D
#implementation HomeViewController
{
NSMutableArray *tableData;
NSDictionary *jsonDict;
NSMutableString *title;
}
-(void) viewDidLoad
{
[super viewDidLoad];
NSError *error;
//I create my data array and the string i'll store my value later on
tableData = [[NSMutableArray alloc] init];
title = [[NSMutableString alloc]init];
// Creating the link for the json api so it fits coordinates ; this works but i edited the locations out to clear the code
NSString *s = [[NSString alloc]initWithFormat:#"http://api.openweathermap.org/data/2.5/weather?lat=%.05f&lon=%.05f", _annotation.coordinate.latitude, _annotation.coordinate.longitude];
// I go online and catch the data of the url stored in S
NSData *jSonData = [NSData dataWithContentsOfURL:[NSURL URLWithString:s]];
// This is a dictionary where all my data is stored from jsonData, keys and values all the way
jsonDict = [NSJSONSerialization JSONObjectWithData:jSonData options:NSJSONReadingMutableContainers error:&error];
// I use the string created previously and assign it the value stored in that dictionary, in the TEMP 'folder', right under MAIN.
title = [[jsonDict objectForKey:#"main"]objectForKey:#"main.temp"];
// I assign that title to a label so it appears in my view.
self.tempLabel.text = title;
...
}
There you go. I'm probably missing something very simple but i've been stuck on this and even if i feel I know what i'm doing, i'm probably missing something. So it'd be great if with the answer you give me, you could also tell me what I did wrong :D
Thank you very much for your support and knowledge. This community is amazing :)
Put a breakpoint after assigning value to jsonDict and use
po jsonDict
in the console to print out what you are getting. Then, adjust the code that extracts the value. And use modern Objective-C syntax for it.
Example
title = jsonDict[#"main"][#"temp"];
Note
po is a debugger command that will print out the contents of an object. If you need to print out the contents of a primitive, use p instead.
My guess is
jsonDict = [NSJSONSerialization JSONObjectWithData:jSonData options:NSJSONReadingMutableContainers error:&error];
is trying to create an nsdictionary, but it the results are coming back as an array. Try this:
NSError *e = nil;
NSArray *jsonArray = [NSJSONSerialization JSONObjectWithData: jsonDict options: NSJSONReadingMutableContainers error: &e];
if (!jsonArray) {
NSLog(#"Error parsing JSON: %#", e);
} else {
for(NSDictionary *item in jsonArray) {
NSLog(#"Item: %#", item);
}
}
This should set you right:
title = [[jsonDict objectForKey:#"main"]objectForKey:#"temp"];
To explain the issue, it seems you were referring to temp using a combination of dot syntax in the key.
EDIT: In response to your error:
That error appears when you're trying to find the length of a string on a value that is not of NSString type. Looks like temp is being returned as a number. So, to do what it looks like you're trying to do, you'll wanna convert [[jsonDict objectForKey:#"main"]objectForKey:#"temp"] to an NSString:
NSNumber *temp = [[jsonDict objectForKey:#"main"]objectForKey:#"temp"];
NSString *tempString = [temp stringValue];
OR
NSString *temp = [[[jsonDict objectForKey:#"main"]objectForKey:#"temp"] stringValue];
That will allow you to get the length: temp.length
**EDIT: Unless you're trying to get the length of the array of weather data...in which case i'd like to see more of that code

Parse json Data in iOS

I know it's a common question, but I am stuck with is API
How to Parse data from this API : http://dl.bahramradan.com/api/1/get/ig
it contain 20 Object and in every object there are 3 other Objects called "image",date" and "caption"
how can I store all "date" values in an NSMUtableArray in ios?
I did this :
NSString *urlStr = [NSString stringWithFormat:#"http://dl.bahramradan.com/api/1/get/ig"];
NSURL *url = [NSURL URLWithString:urlStr];
NSData *json = [NSData dataWithContentsOfURL:url];
NSDictionary *dict = [NSJSONSerialization JSONObjectWithData:json options:0 error:NULL];
NSArray *dateArray = [dict objectForKey:#"date"];
But when I run my app, it crashs on the last line, what is wrong ?
I did not check, if your JSON is valid. But there is one obvious mistake in your code: If the JSON consists of 20 objects, I assume those being contained in an array, rather than in a dict!
So first thing to change is
NSArray *array = [NSJSONSerialization JSONObjectWithData:json options:0 error:NULL];
Then, you want to extract the 'date' values for all items and combine these in another array.
Easiest way to achieve that, is by using a KVC Collection Operator
NSArray *dateArray = [array valueForKeyPath:#"#unionOfObjects.date"];
So, what '#unionOfObjects.date' does, is: going through all the objects in the array, look for each of their 'date' value and combine them in the returned array.
Check out this excellent post about KVC Collection Operators!

Cannot access NSDictionary

I created a JSON using a PHP script.
I am reading the JSON and can see that the data has been correctly read.
However, when it comes to access the objects I get unrecognized selector sent to instance...
Cannot seem to find why that is after too many hours. Any help would be great!
My code looks like that:
NSDictionary *json = [[NSDictionary alloc] init];
json = [NSJSONSerialization JSONObjectWithData:receivedData options:kNilOptions error:&error];
NSLog(#"raw json = %#,%#",json,error);
NSMutableArray *name = [[NSMutableArray alloc] init];
[name addObjectsFromArray: [json objectForKey:#"name"]];
The code crashes when reaching the last line above.
The output like this:
raw json = (
{
category = vacancies;
link = "http://blablabla.com";
name = "name 111111";
tagline = "tagline 111111";
},
{
category = vacancies;
link = "http://blobloblo.com";
name = "name 222222222";
tagline = "tagline 222222222";
}
),(null)
2012-06-23 21:46:57.539 Wind expert[4302:15203] -[__NSCFArray objectForKey:]: unrecognized selector sent to instance 0xdcfb970
HELP !!!
json is an array from what you've shown, not a dictionary. I can tell this because of the parentheses surrounding the whole of the log output for json. Inside the array are dictionaries, which I can tell by the fact that they are surrounded by braces.
So, it looks like you want something like this:
NSError *error = nil;
NSArray *json = [NSJSONSerialization JSONObjectWithData:receivedData options:kNilOptions error:&error];
NSLog(#"raw json = %#,%#",json,error);
NSMutableArray *name = [[NSMutableArray alloc] init];
for (NSDictionary *obj in json) {
[name addObject:[obj objectForKey:#"name"]];
}
As an aside you will notice I have removed the unnecessary initialisation of json to an object before overwriting in the next line with JSONObjectWithData:options:error:. In an ARC world it wouldn't be a leak but it's still completely unnecessary to allocate an object just to get rid of it again a moment later. Also I added in the NSError *error = nil; line since that was not there and was obviously necessary to compile.
The problem appears to be that the root level of your JSON is an array, not a dictionary (note the parenthesis instead of curly brace as the first character in the logged output). Arrays do not have objectForKey selector. Perhaps you intend to take objectAtIndex:0 first, or else iterate over all the the items?
As an aside, the first line of your code makes a completely wasted initialization of an NSDictionary. It is simply overwritten and deallocated on the very next line.

Resources