阅读目录
因为Swift对于类型有非常严格的控制,它在处理JSON时是挺麻烦的,因为它天生就是隐式类型。SwiftyJSON是一个能帮助我们在Swift中使用JSON的开源类库。开始之前,让我们先看一下在Swift中处理JSON是多么痛苦。
在Swift中使用JSON的问题
以Twitter API为例。使用Swift,从tweet中取得一个用户的“name”值应该非常简单。下面就是我们要处理的JSON:
?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
|
[
{
......
"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中,你必须这样使用:
?
1
2
3
4
5
6
7
8
9
10
11
|
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
}
}
}
}
|
或者,你可以用另外的一个方法,但这不易于阅读:
?
1
2
3
4
|
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克隆它:
?
1
|
git clone https: //github .com /lingoer/SwiftyJSON .git
|
回到顶部
基础用法
SwiftyJSON的使用十分的简单:
典型的NSURLSessionTask抓取Twitter的API将产生dataFromNetwork: NSData!:
你首先应该做的事情是初始化JSONValue:
?
1
|
let json = JSONValue(dataFromNetwork)
|
JSONValue是一个枚举类型表示一个典型的JSON数据结构。
你能使用subscripts检索不同的值从原始的JSONValue中,像这样:
?
1
|
let userName:JSONValue = json[ 0 ][ "user" ][ "name" ]
|
注意userName仍然是一个JSONValue。那怎样得到一个字符串呢?
你能用.string属性得到JSON数据表示的真正值。
?
1
|
let userNameString = userName.string!
|
对每一种JSON类型, JSONValue都提供了一种属性检索它:
?
1
2
3
4
5
|
var string: String ?
var number: NSNumber?
var bool: Bool?
var array: Array <JSONValue>?
var object: Dictionary< String , JSONValue>?
|
注意每一种属性都是一个Optional值。这是因为JSON数据能包含任何它定义的有效类型。
因此,建议的方式是用Optional绑定检索值:
?
1
2
3
4
5
6
7
|
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值。
?
1
2
3
|
if let intValue = numberValue.integer{
count += intValue
}
|
回到顶部
枚举(Enumeration)
在Swift中JSONValue实际上是一个枚举:
?
1
2
3
4
5
6
7
8
9
10
11
|
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子句去更有效地获取值:
?
1
2
3
4
5
6
7
8
|
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<JSONVlaue>,它意味着数组里的每一个元素都是一个JSONValue。甚至你从JSONValue中取出一个数组,你仍然可以使用基本的属性去获取元素的值:
?
1
2
3
4
5
|
if let array = json[ "key_of_array" ].array{
if let string = array[ 0 ].string{
//The array[ 0 ] is still a JSONValue!
}
}
|
对象也是一样。因此,推荐的方式是访问每一个数组和对象时使用JSONValue的下标。
?
1
2
3
|
if let string = json[ "key_of_array" ][ 0 ].string{
}
|
实际上,你可以用下标访问一个JSONValue,还不用担心运行时错误导致的崩溃:
?
1
|
let userName = json[ 99999 ][ "wrong_key" ]
|
如果你使用推荐的方式去取数据,它是安全的:
?
1
2
3
|
if let userName = json[ 99999 ][ "wrong_key" ][ "name" ].string{
//It‘s always safe
}
|
回到顶部
打印
JSONValue遵守Printable协议.所以很容易在原始字符串中得到JSON数据:
?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
|
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属性来得到上述字符串。
?
1
|
let printableString = json.description
|
回到顶部
调试与错误处理
要是JSON数据出错或者我们错误地检索数据,那会怎么样呢?你可以使用if语句来测试:
?
1
2
3
4
|
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在哪里出错了.
?
1
2
3
4
5
6
7
8
9
10
11
12
|
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, 请持续关注后续版本。
本文地址:http://www.oschina.net/translate/swiftyjson-how-to-handle-json-in-swift
原文地址:http://www.binpress.com/tutorial/swiftyjson-how-to-handle-json-in-swift/111
时间: 2024-10-06 10:41:12