我需要了解姓名和年龄的JSON人物,并使用Swift 4在Tableview上显示。此外,提供一些链接,以获取不使用Pod的JSON JSON最佳解析方式。
[
{
"id":"01",
"list":"class A",
"People":[
{
"name":"Jack",
"age":"18",
"employed":"Yes"
}
]
},
{
"id":"01",
"list":"class B",
"People":[
{
"name":"Siom",
"age":"17",
"employed":"Yes"
}
]
}
]
我正在尝试使用以下代码,请更正我的代码:
private func readJson() {
do {
if let file = Bundle.main.url(forResource: "test", withExtension: "json") {
let data = try Data(contentsOf: file)
let json = try JSONSerialization.jsonObject(with: data, options: [])
if let object = json as? [String: AnyObject] {
// json is a dictionary
if let person = object["People"] as? [String: AnyObject] {
if let name = person["name"] as? String {
print("Name List\(name)")
}
}
//print(object)
} else if let object = json as? [Any] {
// json is an array
print(object)
} else {
print("JSON is invalid")
}
} else {
print("no file")
}
} catch {
print(error.localizedDescription)
}
}
答案 0 :(得分:0)
使用Swift的Decodable
协议将JSON解析为对象,如下所示:
struct Root: Decodable {
let id: String
let list: String
let people: [People]
// This is a special nested enumeration named CodingKeys that conforms to the CodingKey protocol
// Here we tell decodable not to look for "people" in our json data, instead look for "People" key
// Also notice that we did not provide rawValues for 'id' and 'list', because our json data has same keys
enum CodingKeys: String, CodingKey {
case id
case list
case people = "People"
}
}
struct People: Decodable {
let name: String
let age: String
let employed: String
// In this Decodable struct, we do not provide CodingKeys, because our json dictionary of people has same keys, so this can be left alone
}
let data = """
[{"id":"01","list":"class A","People":[{"name":"Jack","age":"18","employed":"Yes"}]},{"id":"01","list":"class B","People":[{"name":"Siom","age":"17","employed":"Yes"}]}]
""".data(using: .utf8)!
// Since our JSON is an array, here [Root].self tells decoder to look for an array in our json data, if there was a dictionary, instead Root.self will be used, without braces
let root = try JSONDecoder().decode([Root].self, from: data)
现在,我们创建一个People
数组以用作UITableView
数据源:
// Loops through the root array and return peoples array, flattened into a single array
let peoples = root.flatMap{ $0.people }
最后,这是一个快速UITableViewController
,它显示了我们的人民
class ViewController: UITableViewController {
let peoples: [People]
private let cellId = "CellId"
init(category: Category? = nil) {
let data = """
[{"id":"01","list":"class A","People":[{"name":"Jack","age":"18","employed":"Yes"}]},{"id":"01","list":"class B","People":[{"name":"Siom","age":"17","employed":"Yes"}]}]
""".data(using: .utf8)!
let root = try! JSONDecoder().decode([Root].self, from: data)
self.peoples = root.flatMap{ $0.people }
super.init(style: .plain)
self.tableView.tableFooterView = UIView()
}
required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
override func numberOfSections(in tableView: UITableView) -> Int {
return 1
}
override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return self.peoples.count
}
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
var cell: UITableViewCell! = tableView.dequeueReusableCell(withIdentifier: self.cellId)
if (cell == nil) {
cell = UITableViewCell(style:.value1, reuseIdentifier: self.cellId)
}
let people = self.peoples[indexPath.row]
cell.textLabel!.text = people.name
cell.detailTextLabel!.text = people.age
return cell
}
}