如何在 Swift 中优雅地处理 JSON 【已翻译100%】
因为Swift对于类型有非常严格的控制,它在处理JSON时是挺麻烦的,因为它天生就是隐式类型。SwiftyJSON是一个能帮助我们在Swift中使用JSON的开源类库。开始之前,让我们先看一下在Swift中处理JSON是多么痛苦。
在Swift中使用JSON的问题
以Twitter API为例。使用Swift,从tweet中取得一个用户的“name”值应该非常简单。下面就是我们要处理的JSON:
[
{
......
"text": "just another test",
......
"user": {
"name": "OAuth Dancer",
"favourites_count": 7,
"entities": {
"url": {
"urls": [
{
"expanded_url": null,
"url": "http://bit.ly/oauth-dancer",
"indices": [
0,
26
],
"display_url": null
}
]
}
......
},
"in_reply_to_screen_name": null,
},
......]
在Swift中,你必须这样使用:
let jsonObject : AnyObject! = NSJSONSerialization.JSONObjectWithData(dataFromTwitter, options: NSJSONReadingOptions.MutableContainers, error: nil)
if let statusesArray = jsonObject as? NSArray{
if let aStatus = statusesArray[0] as? NSDictionary{
if let user = aStatus["user"] as? NSDictionary{
if let userName = user["name"] as? NSDictionary{
//Finally We Got The Name
}
}
}
}
或者,你可以用另外的一个方法,但这不易于阅读:
let jsonObject : AnyObject! = NSJSONSerialization.JSONObjectWithData(dataFromTwitter, options: NSJSONReadingOptions.MutableContainers, error: nil)
if let userName = (((jsonObject as? NSArray)?[0] as? NSDictionary)?["user"] as? NSDictionary)?["name"]{
//What A disaster above
}
开始
下载在这儿下载SwiftyJSON,或者直接在GitHub克隆它:
git clone https://github.com/lingoer/SwiftyJSON.git
基础用法
SwiftyJSON的使用十分的简单:
典型的NSURLSessionTask抓取Twitter的API将产生dataFromNetwork: NSData!:
你首先应该做的事情是初始化JSONValue:
let json = JSONValue(dataFromNetwork)
JSONValue是一个枚举类型表示一个典型的JSON数据结构。
你能使用subscripts检索不同的值从原始的JSONValue中,像这样:
let userName:JSONValue = json[0]["user"]["name"]
注意userName仍然是一个JSONValue。那怎样得到一个字符串呢?
你能用.string属性得到JSON数据表示的真正值。
let userNameString = userName.string!
对每一种JSON类型, JSONValue都提供了一种属性检索它:
var string: String?
var number: NSNumber?
var bool: Bool?
var array: Array<JSONValue>?
var object: Dictionary<String, JSONValue>?
注意每一种属性都是一个Optional值。这是因为JSON数据能包含任何它定义的有效类型。
因此,建议的方式是用Optional绑定检索值:
if let name = userName.string{
//This could avoid lots of crashes caused by the unexpected data types
}
if let name = userName.number{
//As the value of the userName is Not a number. It won't execute.
}
.number属性产生一个NSNumber值,在Swift中这通常不是很有用。你能用.double或者.integer得到一个Double值或者一个Int值。
if let intValue = numberValue.integer{
count += intValue
}
枚举(Enumeration)
在Swift中JSONValue实际上是一个枚举:
enum JSONValue {
case JNumber(NSNumber)
case JString(String)
case JBool(Bool)
case JNull
case JArray(Array<JSONValue>)
case JObject(Dictionary<String,JSONValue>)
case JInvalid(NSError)
}
你可以使用一个switch子句去更有效地获取值:
let json = JSONValue(jsonObject)
switch json["user_id"]{
case .JString(let stringValue):
let id = stringValue.toInt()
case .JNumber(let numberValue):
let id = numberValue.integerValue
default:
println("ooops!!! JSON Data is Unexpected or Broken")
下标(Subscripts)
注意,在JSON中一个数组结构被包装成intoArray,它意味着数组里的每一个元素都是一个JSONValue。甚至你从JSONValue中取出一个数组,你仍然可以使用基本的属性去获取元素的值:
if let array = json["key_of_array"].array{
if let string = array[0].string{
//The array[0] is still a JSONValue!
}
}
对象也是一样。因此,推荐的方式是访问每一个数组和对象时使用JSONValue的下标。
if let string = json["key_of_array"][0].string{
}
实际上,你可以用下标访问一个JSONValue,还不用担心运行时错误导致的崩溃:
let userName = json[99999]["wrong_key"]
如果你使用推荐的方式去取数据,它是安全的:
if let userName = json[99999]["wrong_key"]["name"].string{
//It's always safe
}
打印
JSONValue遵守Printable协议.所以很容易在原始字符串中得到JSON数据:
let json = JSONValue(dataFromNetwork)
println(json)
/*You can get a well printed human readable raw JSON string:
{
"url": {
"urls": [
{
"expanded_url": null,
"url": "http://bit.ly/oauth-dancer",
"indices": [
0,
26
],
"display_url": null
}
]
}
*/
如果你不想打印出来,你可以使用.description属性来得到上述字符串。
let printableString = json.description
调试与错误处理
要是JSON数据出错或者我们错误地检索数据,那会怎么样呢?你可以使用if语句来测试:
let json = JSONValue(dataFromNetworking)["some_key"]["some_wrong_key"]["wrong_name"]
if json{
//JSONValue it self conforms to Protocol "LogicValue", with JSONValue.JInvalid stands for false and others stands true
}
如果我们尝试使用错误的键值或索引来访问数据,description属性会高数你KeyPath在哪里出错了.
let json = JSONValue(dataFromNetworking)["some_key"]["some_wrong_key"]["wrong_name"]
if json{
} else {
println(json)
//> JSON Keypath Error: Incorrect Keypath "some_wrong_key/wrong_name"
//It always tells you where your key went wrong
switch json{
case .JInvalid(let error):
//An NSError containing detailed error information
}
}
后记
SwiftyJSON的开发将会发布在Github, 请持续关注后续版本。

低调大师中文资讯倾力打造互联网数据资讯、行业资源、电子商务、移动互联网、网络营销平台。
持续更新报道IT业界、互联网、市场资讯、驱动更新,是最及时权威的产业资讯及硬件资讯报道平台。
转载内容版权归作者及来源网站所有,本站原创内容转载请注明来源。
-
上一篇
2016 年 Android 市场的 8 个大胆预测
据techrepublic报道,每年的年底,总是有很多评论者和预测者喜欢猜想来年的情况,为了秉承这种传统,本文对2016年的Android市场提出了8个大胆预测。 1、无锁版设备占统治地位 现在还看不到这点,但无锁版设备将主导Android市场, 而且不是在暗地里这么做,这些设备将进入聚焦灯下,告诉人们为什么它们可能是Android生态系统中最重要的发展。2016年将首次看到,廉价的无锁版 设备将取代三星、HTC、谷歌或摩托罗拉的旗舰设备。无论是一加、小米还是华为,都将发布旗舰杀手,最终打入每个市场并成为“想要的”智能手机。 2、无预装 Android“N”(无论叫什么)将包括让终端用户删除运营商加入的预装软件的能力,这对谷歌和消费者将是一次大赢。虽然Android“N”将是大规模升级,但能删除预装软件将盖过其他任何功能,说明这个功能非常需要。 3、Android“N”将给人深刻印象 Android“N” 的重要变化将包括新的功能丰富的有重启选项的电源菜单。Android“N”也可能有分屏功能,允许用户同时使用2个应用。另外还可能看到下面的功能:主 题引擎、LED通知控制、双击唤醒、更...
-
下一篇
安卓手机控制电脑源代码开源
安卓控制电脑 项目介绍:http://www.oschina.net/p/android-remote-control-computer osc@git地址:http://git.oschina.net/lujianing/android-remote-control-computer 实现功能: 鼠标控制模式: 鼠标的移动 鼠标左键点击 鼠标右键点击 鼠标滑轮 文件的拖动 自定义音量键功能 键盘输入模式: 向电脑发送文字(中英) 回车 退格 以及DOS下的输入 电脑方向键的控制 WSAD模式 和 UP DOWN LEFT RIGHT 音量键可根据用户需求自定义设置功能 手柄控制模式: 横屏下 左边为控制方向 右边为操作 可自定义 左边控制方式为鼠标控制 和 键盘控制 右边 可自定义操作方式 技术点: 多线程+网络编程 JavaAPI的运用(调用操作系统事件) 手机端事件响应的运用多点触控的运用 鼠标移动 手柄模式下键盘控制等的一些算法 应用场合: 讲课或者演示时 不用再拘束于讲台 如PPT的控制等 电脑的远距离控制 看电影聊天再也不用守在电脑前 手机实现游戏手柄的功能 未来畅想: 物...
相关文章
文章评论
共有0条评论来说两句吧...
文章二维码
点击排行
推荐阅读
最新文章
- Docker安装Oracle12C,快速搭建Oracle学习环境
- SpringBoot2编写第一个Controller,响应你的http请求并返回结果
- SpringBoot2整合MyBatis,连接MySql数据库做增删改查操作
- SpringBoot2整合Thymeleaf,官方推荐html解决方案
- CentOS6,7,8上安装Nginx,支持https2.0的开启
- Springboot2将连接池hikari替换为druid,体验最强大的数据库连接池
- MySQL8.0.19开启GTID主从同步CentOS8
- Hadoop3单机部署,实现最简伪集群
- MySQL数据库在高并发下的优化方案
- CentOS7,CentOS8安装Elasticsearch6.8.6