Swift - 利用Codable进行JSON解析

针对常见的几种情况,进行总结。

层次结构嵌套

模型与JSON层次结构对应时

JSON

1
2
3
4
5
6
7
8
9
{
"geometry": {
"type": "Point",
"coordinates": [
-97.089200000000005,
39.745600000000003
]
}
}

模型:

1
2
3
4
5
6
7
struct Entity: Codable {
struct Geometry: Codable {
var type: String
var coordinates: [Double]
}
var geometry: Geometry
}

解析:

1
2
3
4
5
6
let jsonData = jsonText.data(using: .utf8)!

let decoder = JSONDecoder()
do {
let entity = try decoder.decode(Entity.self, from: jsonData)
} catch {}

模型与JSON层次结构不对应时

JSON

1
2
3
4
5
6
7
8
9
{
"geometry": {
"type": "Point",
"coordinates": [
-97.089200000000005,
39.745600000000003
]
}
}

模型:

1
2
3
4
struct Entity: Codable {
var type: String
var coords: [Double]
}

添加新的模型及相关的extension

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
struct EntityWrapper: Codable {
struct Geometry: Codable {
var type: String
var coordinates: [Double]
}
var geometry: Geometry
}

extension EntityWrapper {
var entity: Entity {
Entity(
type: geometry.type,
coords: geometry.coordinates
)
}
}

解析:

1
2
3
4
5
6
7
8
let jsonData = jsonText.data(using: .utf8)!

let decoder = JSONDecoder()
do {
let wrapper = try decoder.decode(EntityWrapper.self, from: jsonData)
let entity = wrapper.entity
print(entity)
} catch {}

不同格式的日期

JSON

1
2
3
4
{
"birthday": "1908-07-16",
"deathday": "1993/10/23"
}

模型:

1
2
3
4
struct Entity: Codable {
var birthday: Date
var deathday: Date
}

解析:

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
let jsonData = jsonText.data(using: .utf8)!

let decoder = JSONDecoder()
// 自定义日期解码策略
decoder.dateDecodingStrategy = .custom({ dec in
let container = try dec.singleValueContainer()
let text = try container.decode(String.self)

let df = DateFormatter()

df.dateFormat = "yyyy-MM-dd"
if let date = df.date(from: text) {
return date
}

df.dateFormat = "yyyy/MM/dd"
if let date = df.date(from: text) {
return date
}

return Date()
})
do {
let entity = try decoder.decode(Entity.self, from: jsonData)
print(entity)
} catch {}

Key、property使用不同的命名规则

指的是JSON与模型,一个使用下划线命名法,另一个使用驼峰命名法

JSON

1
2
3
4
{
"full_name": "Bill Gates",
"country": "USA"
}

模型:

1
2
3
4
struct Entity: Codable {
var fullName: String
var country: String
}

解析:

1
2
3
4
5
6
7
8
9
let jsonData = jsonText.data(using: .utf8)!

let decoder = JSONDecoder()
// 下划线命名法 ----> 驼峰命名法
decoder.keyDecodingStrategy = .convertFromSnakeCase
do {
let entity = try decoder.decode(Entity.self, from: jsonData)
print(entity)
} catch {}

映射不同的Key和property

JSON

1
2
3
4
5
6
7
{
"type": "Point",
"coordinates": [
-97.089200000000005,
39.745600000000003
]
}

模型:

1
2
3
4
5
6
7
8
9
10
struct Entity: Codable {
var type: String
var coords: [Double]

// 建立映射关系
enum CodingKeys: String, CodingKey {
case type
case coords = "coordinates"
}
}

解析:

1
2
3
4
5
6
7
let jsonData = jsonText.data(using: .utf8)!

let decoder = JSONDecoder()
do {
let entity = try decoder.decode(Entity.self, from: jsonData)
print(entity)
} catch {}

Swift - 利用Codable进行JSON解析
https://daniate.github.io/2022/05/07/Swift - 利用Codable进行JSON解析/
作者
Daniate
发布于
2022年5月7日
许可协议