First, you first parse your JSON:
NSError *error;
NSArray *array = [NSJSONSerialization JSONObjectWithData:data options:0 error:&error];
NSAssert(array, @"%s: JSONObjectWithData error: %@", __FUNCTION__, error);
Second, you can then grab the array of locations out of that top-level array, create annotations for each location dictionary in that array, and add it to your map:
// the array of locations is the third object in the top-level array
NSArray *locations = array[2];
// now iterate through this array of locations
for (NSDictionary *location in locations)
{
// grab the latitude and longitude strings
NSString *latitudeString = location[@"lat"];
NSAssert(latitudeString, @"No latitude");
NSString *longitudeString = location[@"lng"];
NSAssert(longitudeString, @"No longitude");
// create the annotation and add it to the map
MKPointAnnotation *annotation = [[MKPointAnnotation alloc] init];
annotation.coordinate = CLLocationCoordinate2DMake([latitudeString doubleValue], [longitudeString doubleValue]);
annotation.title = location[@"name"];
annotation.subtitle = location[@"address"];
[self.mapView addAnnotation:annotation];
}
Having said that, I must say that I don't care for the JSON format:
["VALUE","proyect",[{"id":"1","name":"Frankie Johnnie & Luigo Too","address":"939 W El Camino Real, Mountain View, CA","lat":"37.386337","lng":"-122.085823"},morepoints..]]
It's a questionable design for us to have to divine what the first, second, and third objects in this array are. We shouldn't have to cryptically grab array[2]
to get the array of locations.
Arrays should be used for lists of equivalent items (e.g. the array of locations makes perfect sense). But this top level array is a little more dubious, with three very semantically different types of values, with nothing in the JSON to indicate what these three items are.
If you're stuck with this JSON format, then, fine, the above code should do the job. But hopefully you can change the top level structure here to be a dictionary, rather than an array, where you can use key names to identify the various items in this top-level dictionary, e.g.:
{"id" : "VALUE", "project" : "proyect", "locations" : [{"id":"1","name":"Frankie Johnnie & Luigo Too","address":"939 W El Camino Real, Mountain View, CA","lat":"37.386337","lng":"-122.085823"},morepoints..]}
I didn't know what those first two values were supposed to be, so I just called them id
and project
, but you should obviously use names that truly reflect what those first two values are. But the key concept is to use a dictionary, where you can refer to the array of locations by name. For example, if the JSON was changed like I've suggested here, the code to parse it would become:
NSError *error;
NSDictionary *dictionary = [NSJSONSerialization JSONObjectWithData:data options:0 error:&error];
NSAssert(dictionary, @"%s: JSONObjectWithData error: %@", __FUNCTION__, error);
NSArray *locations = dictionary[@"locations"];
Also, as a stylistic observation, many people would generally represent the latitude and longitude values as numbers (without the quotation marks), and the NSJSONSerialization
would parse them as NSNumber
objects rather than NSString
objects. But that's up to you.