除了我已经使用的方法之外,还有更好的方法来解析此 JSON 吗?
我最近求助于从 Google Maps API 获取我的邮政编码数据。在这个问题的末尾,我添加了从 Google 收到的 JSON 响应字符串的一大段。
在我的代码深处,我得到了响应,并使用 Jonathan Wight 的 TouchJSON 库解析它。这是我的代码
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
}
//
}
请注意我如何通过使用 NSArray 中的特定偏移量来获取类型字典和邮政编码字典。我的问题实际上是这样的,
如何解析 JSON 字符串(最好使用 TouchJSON),而不必对这些数组偏移量进行硬编码?
我发现 Google 地图响应字符串可能会发生变化,并且我的硬编码方法将在那时停止工作。有没有人使用过类似但更强大的方法,他们也愿意在这里分享?
...Google Maps API 示例响应字符串...“目标”邮政编码以粗体突出显示
{ “状态”:“正常”,“结果”:[ { “类型”:[“街道地址”], "formatted_address": "9 Clarendon Pl, Leamington Spa, Warwickshire CV32 5, UK", “地址组件”:[ { “长名称”:“9”, “短名称”:“9”, “类型”:[“街道编号”] }, { "long_name": "克拉伦登 Pl", “短名称”:“A452”, “类型”:[“路线”] }, { "long_name": "利明顿温泉", "short_name": "利明顿温泉", “类型”:[“地点”、“政治”] }, { "long_name": "沃里克", "short_name": "沃里克", “类型”:[“行政区域级别_3”,“政治”] }, { "long_name": "沃里克郡", "short_name": "沃克斯", “类型”:[“行政区域级别_2”,“政治”] }, { "long_name": "英格兰", "short_name": "英格兰", “类型”:[“行政区域级别_1”,“政治”] }, { "long_name": "英国", “短名称”:“GB”, “类型”:[“国家”、“政治”] }, { "long_name": "CV32 5", “短名称”:“CV32 5”, “类型”:[“邮政编码前缀”,“邮政编码”] }], “几何学”: { “地点”: { “纬度”:52.2919849, “液化石油气”:-1.5399505 }, "location_type": "RANGE_INTERPOLATED", “视口”:{ “西南”:{ “纬度”:52.2888374, “液化石油气”:-1.5431216 }, “东北”:{ “纬度”:52.2951326, “液化石油气”:-1.5368264 } }, “界限”:{ “西南”:{ “纬度”:52.2918320, “液化天然气”:-1.5399760 }, “东北”:{ “纬度”:52.2921380, “液化石油气”:-1.5399720 } } } }, { “类型”:[“邮政编码”], "formatted_address": "利明顿温泉, 沃里克郡 CV32 5LD, 英国", “地址组件”:[ { “long_name”:“CV32 5LD”, "short_name": "CV32 5LD", “类型”:[“邮政编码”] }, { "long_name": "利明顿温泉", "short_name": "利明顿温泉", “类型”:[“地点”、“政治”] },……接下来还有更多 JSON
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
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
我从未使用过 TouchJSON,但在我看来,您的硬编码偏移量是存在的,因为您只期望一个结果,但 Google Maps API 足够灵活,可以返回多个结果。事实上,
objectAtIndex:1
表明您正在获取第二个结果集,因此您编写的代码实际上取决于至少有两个结果。即使我在那里弄错了细节,我怀疑你真正想做的事情而不是
NSDictionary* types = [results objectAtIndex:1];
更像是:如果你不知道要了解谓词如何工作,您需要首先阅读 Apple 的谓词编程指南,以了解如何设置谓词(我在上面标记为
yourPredicateHere
的内容)。 http://developer.apple.com/library/ mac/#documentation/Cocoa/Conceptual/Predicates/predicates.htmlI've never used TouchJSON, but it appears to me that your hardcoded offsets are there because you expect only one result, but Google Maps API is flexible enough to return multiple results. In fact, where you have
objectAtIndex:1
suggests that you are taking the second result set, so the code you've written is actually dependent on there being at least two results.Even if I've gotten the details wrong there, I suspect what you really want to do instead of
NSDictionary* types = [results objectAtIndex:1];
is something more like:If you don't know how predicates work, you'll want to read Apple's Predicate Programming Guide first to figure out how to set your predicate (the thing that I labeled
yourPredicateHere
above). http://developer.apple.com/library/mac/#documentation/Cocoa/Conceptual/Predicates/predicates.html