您的位置:首页 > 移动开发 > Swift

Swift原生JSON解析和第三方解析对比

2015-12-30 23:15 465 查看
如果 app 需要有网络功能并且有一个后端服务器处理和返回数据的话,那么现在基本上要和 JSON 打交道是没跑儿了的。在 Swift 里处理 JSON 其实是一件挺棘手的事情,因为 Swift 对于类型的要求非常严格,所以在解析完 JSON 之后想要从结果的 
AnyObject
 中获取某个键值是一件非常麻烦的事情。举个例子,我们使用 
NSJSONSerialization
 解析完一个
JSON 字符串后,得到的是 
AnyObject?

// jsonString
{"menu": {
"id": "file",
"value": "File",
"popup": {
"menuitem": [
{"value": "New", "onclick": "CreateNewDoc()"},
{"value": "Open", "onclick": "OpenDoc()"},
{"value": "Close", "onclick": "CloseDoc()"}
]
}
}}

let jsonString = //...

let json: AnyObject = try! NSJSONSerialization.JSONObjectWithData(
jsonString.dataUsingEncoding(NSUTF8StringEncoding, allowLossyConversion: true)!,
options: [])


我们如果想要访问 menu 里的 popup 中 第一个 menuitem 的 value 值的话,最正规的情况下,需要写这样的代码:
if let jsonDic = json as? NSDictionary {
if let menu = jsonDic["menu"] as? [String: AnyObject] {
if let popup: AnyObject = menu["popup"] {
if let popupDic = popup as? [String: AnyObject] {
if let menuItems: AnyObject = popupDic["menuitem"] {
if let menuItemsArr = menuItems as? [AnyObject] {
if let item0 = menuItemsArr[0]
as? [String: AnyObject] {
if let value: AnyObject = item0["value"] {
print(value)
}
}
}
}
}
}
}
}
// 输出 New


什么?你难道把这段代码看完了?我都不忍心写下去了...如果你真的想要坚持这么做的话,我只能说呵呵,并且祝你好运了。

当然,在 Swift 1.2 中,我们可以在同一个 
if let
 语句中进行 unwrap,这样会比原来稍好一些,但是依旧十分麻烦:
if let jsonDic = json as? NSDictionary,
menu = jsonDic["menu"] as? [String: AnyObject],
popup = menu["popup"],
popupDic = popup as? [String: AnyObject],
menuItems = popupDic["menuitem"],
menuItemsArr = menuItems as? [AnyObject],
item0 = menuItemsArr[0] as? [String: AnyObject],
value = item0["value"]
{
print(value)
}


那么,我们应该怎么做呢?在上面的代码中,最大的问题在于我们为了保证类型的正确性,做了太多的转换和判断。我们并没有利用一个有效的 JSON 容器总应该是字典或者数组这个有用的特性,而导致每次使用下标取得的值都是需要转换的 
AnyObject
。如果我们能够重载下标的话,就可以通过下标的取值配合 
Array
 和 
Dictionay
 的
Optional Binding 来简单地在 JSON 中取值。鉴于篇幅,我们在这里不给出具体的实现。感兴趣的读者可以移步看看 json-swift 或者 SwiftyJSON 这样的项目,它就使用了重载下标访问的方式简化了
JSON 操作。使用这个工具,上面的访问可以简化为下面的类型安全的样子:
// 使用 SwiftJSON
if let value = JSON(json)["menu"]["popup"]["menuitem"][0]["value"].string {
print(value)
}


这样就简单多了。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  IOS Swift JSON