I have recently had recourse to get my postcode data from Google Maps API. At the end of this question I have included a large snippet of the JSON response string that I receive from Google.
Deep in my code I get the response and I parse it using the TouchJSON library from Jonathan Wight. This is my code
NSStringEncoding encoding;
// Fetch data from web service.
NSString *jsonString = [NSString stringWithContentsOfURL:url usedEncoding:&encoding error:nil];
// Process JSON data returned from web service.
NSData *jsonData = [jsonString dataUsingEncoding:NSUTF32BigEndianStringEncoding];
NSDictionary *dictionary = [[CJSONDeserializer deserializer] deserializeAsDictionary:jsonData error:nil];
if (jsonString == nil)
{
// bah
} else if (![self isCancelled]) {// Check to see if we have been cancelled.
if (dictionary) {
NSArray* results = [dictionary objectForKey:@"results"];
NSDictionary* types = [results objectAtIndex:1];
NSArray* address_components = [types objectForKey:@"address_components"];
NSDictionary* postcodes = [address_components objectAtIndex:0];
NSString* postcode = [postcodes objectForKey:@"long_name"];
// do stuff with the postcode
}
//
}
Notice how I get the types dictionary and the postcodes dictionary by using a specific offset in an NSArray. My question is really this,
How can I parse the JSON string (preferably using TouchJSON) without having to hard code those array offsets?
It strikes me that the Google Maps response string may be subject to change and my hard coded approach would stop working at that point. Has anyone out there used a similar but more robust approach that they would be willing too share here?
...Google Maps API sample response string... The 'target' postcode is highlighted in bold
{ "status": "OK", "results": [ { "types": [ "street_address" ], "formatted_address": "9 Clarendon Pl, Leamington Spa, Warwickshire CV32 5, UK", "address_components": [ { "long_name": "9", "short_name": "9", "types": [ "street_number" ] }, { "long_name": "Clarendon Pl", "short_name": "A452", "types": [ "route" ] }, { "long_name": "Leamington Spa", "short_name": "Leamington Spa", "types": [ "locality", "political" ] }, { "long_name": "Warwick", "short_name": "Warwick", "types": [ "administrative_area_level_3", "political" ] }, { "long_name": "Warwickshire", "short_name": "Warks", "types": [ "administrative_area_level_2", "political" ] }, { "long_name": "England", "short_name": "England", "types": [ "administrative_area_level_1", "political" ] }, { "long_name": "United Kingdom", "short_name": "GB", "types": [ "country", "political" ] }, { "long_name": "CV32 5", "short_name": "CV32 5", "types": [ "postal_code_prefix", "postal_code" ] } ], "geometry": { "location": { "lat": 52.2919849, "lng": -1.5399505 }, "location_type": "RANGE_INTERPOLATED", "viewport": { "southwest": { "lat": 52.2888374, "lng": -1.5431216 }, "northeast": { "lat": 52.2951326, "lng": -1.5368264 } }, "bounds": { "southwest": { "lat": 52.2918320, "lng": -1.5399760 }, "northeast": { "lat": 52.2921380, "lng": -1.5399720 } } } }, { "types": [ "postal_code" ], "formatted_address": "Leamington Spa, Warwickshire CV32 5LD, UK", "address_components": [ { "long_name": "CV32 5LD", "short_name": "CV32 5LD", "types": [ "postal_code" ] }, { "long_name": "Leamington Spa", "short_name": "Leamington Spa", "types": [ "locality", "political" ] }, ......... lots more JSON follows