如何通过使用Swift 4从JSON获取特定值?

时间:2018-07-22 16:14:48

标签: ios json swift tableview

我需要了解姓名和年龄的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)
        }
    }

1 个答案:

答案 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
    }

}

这是您得到的: enter image description here