Swift原生JSON解析和第三方解析对比
2015-12-30 23:15
465 查看
如果 app 需要有网络功能并且有一个后端服务器处理和返回数据的话,那么现在基本上要和 JSON 打交道是没跑儿了的。在 Swift 里处理 JSON 其实是一件挺棘手的事情,因为 Swift 对于类型的要求非常严格,所以在解析完 JSON 之后想要从结果的
JSON 字符串后,得到的是
我们如果想要访问 menu 里的 popup 中 第一个 menuitem 的 value 值的话,最正规的情况下,需要写这样的代码:
什么?你难道把这段代码看完了?我都不忍心写下去了...如果你真的想要坚持这么做的话,我只能说呵呵,并且祝你好运了。
当然,在 Swift 1.2 中,我们可以在同一个
那么,我们应该怎么做呢?在上面的代码中,最大的问题在于我们为了保证类型的正确性,做了太多的转换和判断。我们并没有利用一个有效的 JSON 容器总应该是字典或者数组这个有用的特性,而导致每次使用下标取得的值都是需要转换的
Optional Binding 来简单地在 JSON 中取值。鉴于篇幅,我们在这里不给出具体的实现。感兴趣的读者可以移步看看 json-swift 或者 SwiftyJSON 这样的项目,它就使用了重载下标访问的方式简化了
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) }
这样就简单多了。
相关文章推荐
- 峰回路转,Firefox 浏览器即将重返 iOS 平台
- 峰回路转,Firefox 浏览器即将重返 iOS 平台
- 不可修补的 iOS 漏洞可能导致 iPhone 4s 到 iPhone X 永久越狱
- iOS 12.4 系统遭黑客破解,漏洞危及数百万用户
- Apple Swift学习教程
- 每日安全资讯:NSO,一家专业入侵 iPhone 的神秘公司
- XML 与 JSON 优劣对比
- [转][源代码]Comex公布JailbreakMe 3.0源代码
- 介绍 Fedora 上的 Swift
- VBA将excel数据表生成JSON文件
- newtonsoft.json解析天气数据出错解决方法
- vbs 解析json jsonp的方法
- Extjs4如何处理后台json数据中日期和时间
- C#实现将类的内容写成JSON格式字符串的方法
- JQuery ajax返回JSON时的处理方式 (三种方式)
- jquery JSON的解析方式示例介绍
- c#版json数据解析示例分享
- ASP JSON类文件的使用方法