扬庆の博客

Swift语法(2)- Codable

字数统计: 1.1k阅读时长: 5 min
2021/04/23 Share

Swift语法(2)- Codable

Swift 单利

Swift3.0 移除了 dispatch_once

1
2
3
4
5
6
7
8
class MyManager {
static let share = MyManager()
private init() {}
}

let manager1 = MyManager.share
let manager2 = MyManager.share
// manager1 和 manager2 内存地址都是一样的,达到绝对的一份内存空间

swift - Codable

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
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
// 只要一个类型中所有的成员都实现了 Codable, 那么这个类型也就可以自动满足 Codable 的要求.
//
//如果 JSON 中的key 和类型中的变量名不一致的话 ( 这很常见, 因为 JSON 中往往使用下划线命名 key 值, 而 Swift 中
//的命名规则一般是驼峰式), 我么你还需要在对应类中声明 CodingKeys 枚举, 并用合适的键值覆盖对应的默认值,下面的MenuItem都属于
//这种情况.
//*/
//
//struct Obj: Codable {
//
// let menu: Menu
//
// struct Menu: Codable {
// let id: String
// let value: String
// let popup: Popup
// }
//
// struct Popup: Codable {
//
// let menuItem: [MenuItem]
//
// enum CodingKeys: String, CodingKey {
// case menuItem = "menuitem"
// }
// }
//
// struct MenuItem: Codable {
// let value: String
// let onClick: String
//
// enum CodingKeys: String, CodingKey {
// case value
// case onClick = "onclick"
// }
// }
//}
//
//// 编码: 数据实例对象 -> json 或者 property list
//// > 或者 JSONEncoder: 将 Codable 类型数据编码为 JSON 数据
//
//// 解码: json 或者 property list -> 数据实例对象
//// > JSONDecoder: 将 JSON 数据解码为指定的 Codable 类型数据
//
//
//struct Person: Codable {
// var id: Int
// var name: String
// var age: Int
// var isMale: Bool
//}
//
//struct Team: Codable {
// var master: Person
// var memebers: [Person]
//}
//
//// 编码
//let jack = Person(id: 1, name: "jack", age: 12, isMale: true)
//if let jackData = try? JSONEncoder().encode(jack) {
// print(String(data: jackData, encoding: .utf8))
//}
//
//// 解码
//let jsonString = """
//{
// "id": 2,
// "name": "lucy",
// "age": 11,
// "isMale": false
//}
//"""
//
//if let json = jsonString.data(using: .utf8) {
// let lucy = try? JSONDecoder().decode(Person.self, from: json)
// print(lucy!)
//}

// ****** Codable 使用的基本步骤 ******
// 1. 自定义类型遵守 Codable 协议
// 2. 使用编码器实现自定义类型数据的编码和解码

struct Person: Codable {
var id: Int
var name: String
var age: Int
var isMale: Bool
var description: String = "person"

enum CodingKeys: String, CodingKey {
case id = "身份证号"
case name = "姓名"
case age = "年龄"
case isMale
}
}

// 解码
let jsonString = """
{
"id": 2,
"name": "lucy",
"age": 11,
"isMale": false
}
"""
//
//let jsonString = """
//{
// "身份证号": 2,
// "姓名": "lucy",
// "年龄": 11,
// "isMale": false
//}
//"""

//if let dt = jsonString.data(using: .utf8) {
// let p = try? JSONDecoder().decode(Person.self, from: dt)
// print(p)
//}

//let tim = Person(id: 3, name: "tim", age: 10, isMale: true, description: "")
//
//if let timData = try? JSONEncoder().encode(tim) {
// print(String(data: timData, encoding: .utf8)!)
//}
// 打印: {"姓名":"tim","isMale":true,"年龄":10,"身份证号":3}




// **** 自定义 encode 和 decode ****

struct Size: Codable {
var width: Double
var height: Double
}

struct Point: Codable {
var x: Double
var y: Double
}


//struct Rect: Codable {
// var position: Point
// var size: Size
//}


//let rect = Rect(position: Point(x: 0.0, y: 0.0), size: Size(width: 20, height: 20))
//
//if let rectData = try? JSONEncoder().encode(rect) {
// let jstr = String(data: rectData, encoding: .utf8)
// print(jstr!)
//}
// {"position":{"x":0,"y":0},"size":{"width":20,"height":20}}

struct Rect {
var position: Point
var size: Size

enum CodingKeys: String,CodingKey{
case x
case y
case width
case height
}
}

extension Rect: Encodable {

func encode(to encoder: Encoder) throws {
var container = encoder.container(keyedBy: CodingKeys.self)
try container.encode(position.x, forKey:.x)
try container.encode(position.y, forKey: .y)
try container.encode(size.width, forKey: .width)
try container.encode(size.height, forKey: .height)
}
}

extension Rect: Decodable {

init(from decoder: Decoder) throws {
let container = try decoder.container(keyedBy: CodingKeys.self)
let x = try container.decode(Double.self, forKey: .x)
let y = try container.decode(Double.self, forKey: .y)
position = Point(x: x, y: y)

let width = try container.decode(Double.self, forKey: .width)
let height = try container.decode(Double.self, forKey: .height)
size = Size(width: width, height: height)
}
}

let rect = Rect(position: Point(x: 0.0, y: 0.0), size: Size(width: 10.0, height: 10.0))

if let dt = try? JSONEncoder().encode(rect) {
print(String(data: dt, encoding: .utf8)!)
}

//打印: {"y":0,"x":0,"width":10,"height":10}


let rectString = """
{
"x": 3,
"y": 3,
"width": 2.5,
"height": 2.5
}
"""
if let data = rectString.data(using: .utf8) {
let p = try? JSONDecoder().decode(Rect.self, from: data)
print(p!)
}

// 打印: Rect(position: __lldb_expr_11.Point(x: 3.0, y: 3.0), size: __lldb_expr_11.Size(width: 2.5, height: 2.5))

1
2
3
4
5
6
7
8
9
10
11
12
13
14
import UIKit

// 网络通信中使用
struct Response: Codable {
var status: Int
var message: String
}

let res = Response(status: 200, message: "OK")
let resDt = try? JSONEncoder().encode(res)

print(String(data: resDt!, encoding: .utf8)!)

// {"status":200,"message":"OK"}

参考

CATALOG
  1. 1. Swift语法(2)- Codable
    1. 1.0.1. Swift 单利
    2. 1.0.2. swift - Codable