https://blog.csdn.net/ly410726/article/details/80235007
1,SwiftyJSON介绍与配置
SwiftyJSON是个使用Swift语言编写的开源库,可以让我们很方便地处理JSON数据(解析数据、生成数据)。
GitHub地址:
https://github.com/SwiftyJSON/SwiftyJSON
使用配置:直接将 SwiftyJSON.swift 添加到项目中即可。
使用配置:直接将 SwiftyJSON.swift 添加到项目中即可。
同 JSONSerializationSwiftyJSON 相比,在获取多层次结构的JSON数据时。SwiftyJSON不需要一直判断这个节点是否存在,是不是我们想要的class,下一个节点是否存在,是不是我们想要的class…。同时,SwiftyJSON内部会自动对optional(可选类型)进行拆包(Wrapping ),大大简化了代码。
下面通过几个样例作为演示。(本文代码均已升级至 Swift3)
为便于测试比较,我们先将JSON格式的字符串转为Data:
(2)使用JSONSerializationSwiftyJSON解析
比如我们要取第一条联系人的第一个电话号码,每个级别都判断就很麻烦,代码如下:
即使使用optional来简化一下,代码也不少:
(3)使用SwiftyJSON解析:
不用担心数组越界,不用判断节点,拆包什么的,代码如下:
如果没取到值,还可以走到错误处理来了,打印一下看看错在哪:
3,获取网络数据,并使用SwiftyJSON解析
除了解析本地的JSON数据,我们其实更常通过url地址获取远程数据并解析。
(1)与URLSession结合
(2)与Alamofire结合
4,获取值
(2)使用简单的数据类型创建JSON对象
(3)使用数组或字典数据创建JSON对象
(1)比如我们有一个如下的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
|
[
{
"name"
:
"hangge"
,
"age"
: 100,
"phones"
: [
{
"name"
:
"公司"
,
"number"
:
"123456"
},
{
"name"
:
"家庭"
,
"number"
:
"001"
}
]
},
{
"name"
:
"big boss"
,
"age"
: 1,
"phones"
: [
{
"name"
:
"公司"
,
"number"
:
"111111"
}
]
}
]
|
1
2
3
4
5
|
let
jsonStr =
"[{\"name\": \"hangge\", \"age\": 100, \"phones\": [{\"name\": \"公司\",\"number\": \"123456\"}, {\"name\": \"家庭\",\"number\": \"001\"}]}, {\"name\": \"big boss\",\"age\": 1,\"phones\": [{ \"name\": \"公司\",\"number\": \"111111\"}]}]"
if
let
jsonData = jsonStr.data(using:
String
.
Encoding
.utf8, allowLossyConversion:
false
) {
//.........
}
|
(2)使用JSONSerializationSwiftyJSON解析
比如我们要取第一条联系人的第一个电话号码,每个级别都判断就很麻烦,代码如下:
1
2
3
4
5
6
7
|
if
let
userArray = try?
JSONSerialization
.jsonObject(with: jsonData,
options: .allowFragments)
as
? [[
String
:
AnyObject
]],
let
phones = userArray?[0][
"phones"
]
as
? [[
String
:
AnyObject
]],
let
number = phones[0][
"number"
]
as
?
String
{
// 找到电话号码
print
(
"第一个联系人的第一个电话号码:"
,number)
}
|
1
2
3
4
5
6
|
if
let
userArray = try?
JSONSerialization
.jsonObject(with: jsonData,
options: .allowFragments)
as
? [[
String
:
AnyObject
]],
let
number = (userArray?[0][
"phones"
]
as
? [[
String
:
AnyObject
]])?[0][
"number"
]
as
?
String
{
// 找到电话号码
print
(
"第一个联系人的第一个电话号码:"
,number)
}
|
(3)使用SwiftyJSON解析:
不用担心数组越界,不用判断节点,拆包什么的,代码如下:
1
2
3
4
5
|
let
json =
JSON
(data: jsonData)
if
let
number = json[0][
"phones"
][0][
"number"
].string {
// 找到电话号码
print
(
"第一个联系人的第一个电话号码:"
,number)
}
|
1
2
3
4
5
6
7
8
|
let
json =
JSON
(data: jsonData)
if
let
number = json[0][
"phones"
][0][
"number"
].string {
// 找到电话号码
print
(
"第一个联系人的第一个电话号码:"
,number)
}
else
{
// 打印错误信息
print
(json[0][
"phones"
][0][
"number"
])
}
|
除了解析本地的JSON数据,我们其实更常通过url地址获取远程数据并解析。
(1)与URLSession结合
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
|
//创建URL对象
//创建请求对象
let
request =
URLRequest
(url: url!)
let
dataTask =
URLSession
.shared.dataTask(with: request,
completionHandler: {(data, response, error) ->
Void
in
if
error !=
nil
{
print
(error)
}
else
{
let
json =
JSON
(data: data!)
if
let
number = json[0][
"phones"
][0][
"number"
].string {
// 找到电话号码
print
(
"第一个联系人的第一个电话号码:"
,number)
}
}
})
as
URLSessionTask
//使用resume方法启动任务
dataTask.resume()
|
(2)与Alamofire结合
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
|
//创建URL对象
Alamofire
.request(url).validate().responseJSON { response
in
switch
response.result.isSuccess {
case
true
:
if
let
value = response.result.value {
let
json =
JSON
(value)
if
let
number = json[0][
"phones"
][0][
"number"
].string {
// 找到电话号码
print
(
"第一个联系人的第一个电话号码:"
,number)
}
}
case
false
:
print
(response.result.error)
}
}
|
(1)可选值获取(Optional getter)
通过.number、.string、.bool、.int、.uInt、.float、.double、.array、.dictionary、int8、Uint8、int16、Uint16、int32、Uint32、int64、Uint64等方法获取到的是可选择值,我们需要自行判断是否存在,同时不存在的话可以获取具体的错误信息。
(2)不可选值获取(Non-optional getter)
使用 xxxValue 这样的属性获取值,如果没获取到的话会返回一个默认值。省得我们再判断拆包了。
(3)获取原始数据(Raw object)
5,设置值
6,下标访问(Subscript)
可以通过数字、字符串、数组类型的下标访问JSON数据的层级与属性。比如下面三种方式的结果都是一样的:
7,循环遍历JSON对象中的所有数据
(1)如果JSON数据是数组类型(Array)
(2)如果JSON数据是字典类型(Dictionary)
8,构造创建JSON对象数据
(1)空的JSON对象
通过.number、.string、.bool、.int、.uInt、.float、.double、.array、.dictionary、int8、Uint8、int16、Uint16、int32、Uint32、int64、Uint64等方法获取到的是可选择值,我们需要自行判断是否存在,同时不存在的话可以获取具体的错误信息。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
|
//int
if
let
age = json[0][
"age"
].int {
print
(age)
}
else
{
//打印错误信息
print
(json[0][
"age"
])
}
//String
if
let
name = json[0][
"name"
].string {
print
(name)
}
else
{
//打印错误信息
print
(json[0][
"name"
])
}
|
使用 xxxValue 这样的属性获取值,如果没获取到的话会返回一个默认值。省得我们再判断拆包了。
1
2
3
4
5
6
7
8
9
10
11
|
//If not a Number or nil, return 0
let
age:
Int
= json[0][
"age"
].intValue
//If not a String or nil, return ""
let
name:
String
= json[0][
"name"
].stringValue
//If not a Array or nil, return []
let
list:
Array
<
JSON
> = json[0][
"phones"
].arrayValue
//If not a Dictionary or nil, return [:]
let
phone:
Dictionary
<
String
,
JSON
> = json[0][
"phones"
][0].dictionaryValue
|
(3)获取原始数据(Raw object)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
|
let
jsonObject = json.object
as
AnyObject
let
jsonObject = json.rawValue
as
AnyObject
//JSON转化为Data
let
data = json.rawData()
//JSON转化为String字符串
if
let
string = json.rawString() {
//Do something you want
}
//JSON转化为Dictionary字典([String: AnyObject]?)
if
let
dic = json.dictionaryObject {
//Do something you want
}
//JSON转化为Array数组([AnyObject]?)
if
let
arr = json.arrayObject {
//Do something you want
}
|
5,设置值
1
2
3
4
|
json[0][
"age"
].int = 101
json[0][
"name"
].string =
"hangge.com"
json[0][
"phones"
].arrayObject = [[
"name"
:
"固话"
,
"number"
:110],[
"name"
:
"手机"
,
"number"
:120]]
json[0][
"phones"
][0].dictionaryObject = [
"name"
:
"固话"
,
"number"
:100]
|
6,下标访问(Subscript)
可以通过数字、字符串、数组类型的下标访问JSON数据的层级与属性。比如下面三种方式的结果都是一样的:
1
2
3
4
5
6
7
8
9
|
//方式1
let
number = json[0][
"phones"
][0][
"number"
].stringValue
//方式2
let
number = json[0,
"phones"
,0,
"number"
].stringValue
//方式3
let
keys:[
JSONSubscriptType
] = [0,
"phones"
,0,
"number"
]
let
number = json[keys].stringValue
|
(1)如果JSON数据是数组类型(Array)
1
2
3
|
for
(index,subJson):(
String
,
JSON
)
in
json {
print
(
"\(index):\(subJson)"
)
}
|
1
2
3
|
for
(key,subJson):(
String
,
JSON
)
in
json[0] {
print
(
"\(key):\(subJson)"
)
}
|
(1)空的JSON对象
1
|
let
json:
JSON
=
nil
|
(2)使用简单的数据类型创建JSON对象
1
2
3
4
5
6
7
8
9
10
11
|
//StringLiteralConvertible
let
json:
JSON
=
"I'm a son"
//IntegerLiteralConvertible
let
json:
JSON
= 12345
//BooleanLiteralConvertible
let
json:
JSON
=
true
//FloatLiteralConvertible
let
json:
JSON
= 2.8765
|
(3)使用数组或字典数据创建JSON对象
1
2
3
4
5
6
7
8
9
10
11
12
|
//DictionaryLiteralConvertible
let
json:
JSON
= [
"I"
:
"am"
,
"a"
:
"son"
]
//ArrayLiteralConvertible
let
json:
JSON
= [
"I"
,
"am"
,
"a"
,
"son"
]
//Array & Dictionary
var
json:
JSON
= [
"name"
:
"Jack"
,
"age"
: 25,
"list"
: [
"a"
,
"b"
,
"c"
, [
"what"
:
"this"
]]]
json[
"list"
][3][
"what"
] =
"that"
json[
"list"
,3,
"what"
] =
"that"
let
path:[
JSONSubscriptType
] = [
"list"
,3,
"what"
]
json[path] =
"that"
|
原文出自:www.hangge.com 转载请保留原文链接:http://www.hangge.com/blog/cache/detail_968.html