{
"jsonData": [
{
"title": "水果",
"items": [
"苹果",
"香蕉",
"梨",
"西瓜"
]
},
{
"title": "汽车",
"items": [
"宝马",
"奔驰",
"本田",
"起亚"
]
},
{
"title": "省份",
"items": [
"北京",
"天津",
"河北"
]
}
]
}
Json是key-value的键值对,根据Json中的内容设计相应的数据结构才能正确解析数据:变量名和key一致、变量类型和value类型一致
Result
"jsonData"
,value是另一个自定义结构体ResultItem
的数组ResultItem
结构体:"title"
,value是具体种类、类型为String
;"items"
,value是该种类具体内容、类型为String
数组Codable
协议Codable
协议,与NSCoding
协议不同的是:如果自定义的类中全都是基本数据类型、基本对象类型,它们都已经实现了Codable
协议,那么这个自定义的类也默认实现了Codable
,无需再实现编解码,只需要在自定义的类声明它遵守Codable
协议即可struct Result: Codable {
let jsonData: [ResultItem]
}
struct ResultItem: Codable {
let title: String
let items: [String]
}
mainBundle
获取 json 文件路径,因为可能找不到路径,比如文件名、类型名参数写错或文件不存在,因此要用guard ... else
处理读不到的情况URL(fileURLWithPath:)
方法将文件路径转为 urlguard let path = Bundle.main.path(forResource: "data",ofType: "json")
else{
return
}
let url = URL(fileURLWithPath: path)
Data(contentsOf: url)
和JSONDecoder().decode()
都可能失败throw
异常,因此放在do{} catch{}
中,并try
result
就成了nil
,因此声明为可选型var result: Result?
do {
let jsonData = try Data(contentsOf: url)
result = try JSONDecoder().decode(Result.self, from: jsonData)
}
catch {
print("Error:\(error)")
}
{//代码体}()
,匿名函数格式,小括号表示立即调用大括号中定义的函数体let tableView:UITableView = {
let table = UITableView(frame: .zero, style: .grouped)
table.register(UITableViewCell.self, forCellReuseIdentifier: "cell")
return table
}()
override func viewDidLoad() {
super.viewDidLoad()
parseJson()
//加入当前视图的子树图,并设置在父视图中的位置frame
view.addSubview(tableView)
tableView.frame = view.bounds
//设置数据源和代理
tableView.delegate = self
tableView.dataSource = self
}
ResultItem
数组中的元素个数,result
为nil
时返回 0func numberOfSections(in tableView: UITableView) -> Int {
return result?.jsonData.count ?? 0
}
ResultItem
的title
值func tableView(_ tableView: UITableView, titleForHeaderInSection section: Int) -> String? {
return result?.jsonData[section].title
}
ResultItem
的items
数组中的元素个数func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
if let res = result {
return res.jsonData[section].items.count
}
return 0
}
ResultItem
的items
数组中的值func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let contents = result?.jsonData[indexPath.section].items[indexPath.row]
let cell = tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath)
cell.textLabel?.text = contents
return cell
}