当对象包含其他对象的数组时,如何解析JSON?

时间:2016-11-02 13:46:23

标签: ios arrays json swift

我一直在尝试在Swift中解析JSON,其中对象包含其他对象的数组。像这样:

{
  "people": [
    {
      "name": "Life Sciences",
      "id": "4343435",

      "children" : [
        {
          "name": "name1",
          "id" : "5344444",
        },

        {
          "name": "name2",
          "id" : "5134343",
        },
      .....

我需要能够访问name和id属性,但我似乎无法弄清楚我在下面的代码中做错了什么。我的JSON文件包含所有必要的数据,然而,当我尝试循环子数组时,我在解开可选的“ 错误时不断发现 ”意外找到了nil。在该行之前,JSON被正确解析并且有效。

let loadURL = "https:// ....."
var people = [Person]()

func getPersonData() {
    let request = URLRequest(url: URL(string: loadURL)!)
    let urlSession = URLSession.shared
    let task = urlSession.dataTask(with: request, completionHandler: { (data, response, error) -> Void in
        if let error = error {
            print(error)
            return
        }
        // Parse JSON data
        if let data = data {
            self.people = self.parseJsonData(data)
            OperationQueue.main.addOperation{() -> Void in
                self.tableView.reloadData()
            }
        }
    })
    task.resume()
}

func parseJsonData(_ data: Data) -> [Person] {
    var people = [Person]()

    do {
        let jsonResult = try JSONSerialization.jsonObject(with: data, options: JSONSerialization.ReadingOptions.mutableContainers) as? NSDictionary

        // Parse JSON data
        let jsonPeople = jsonResult?["people"] as! [AnyObject]
        for jsonPerson in jsonPeople {
            let person = Person()
            person.name = jsonPerson["name"] as! String
            person.id = jsonPerson["id"] as! String

            //ERROR//: "unexpectedly found nil when unwrapping optional..."
            let jsonChildren = jsonResult?["children"] as! [AnyObject]
            for jsonChild in jsonChildren {
                let child = Child()
                child.name = jsonEntrance["name"] as! String
                child.age = jsonEntrance["age"] as! Int

                person.children.append(child)
            }

            people.append(person)
        }
    } catch {
        print(error)
    }
    return people
}

4 个答案:

答案 0 :(得分:1)

你在这里犯了一个错误:

let jsonChildren = jsonResult?["children"] as! [AnyObject]

应该是:

let jsonChildren = jsonPerson["children"] as! [AnyObject]

答案 1 :(得分:0)

可能你的JSON数据在某些方面没有"孩子"值,尽量避免强制转换为[AnyObject]。您可以尝试以这种方式更改它:

-f

此外,您可以尝试使用SwiftyJSON,它将帮助您更轻松地完成json数据处理。

答案 2 :(得分:0)

您的代码看起来不错,但问题是您正在搜索错误的字典。你的'jsonResult'键没有'儿童'的钥匙。但是你的'jsonPerson'对象有一个'儿童'键。替换下面的代码行 -

let jsonChildren = jsonResult?["children"] as! [AnyObject]

将此行替换为此行 -

            let jsonChildren = jsonPerson?["children"] as! [AnyObject]

答案 3 :(得分:0)

首先,JSON不代表代码中的实际JSON。

其次,除非你别无选择,否则永远不会在Swift中使用NSDictionary

第三,将包含字典的JSON数组强制转换为[[String:Any]],永不转发[Any(Object)]

首先,Swift 3中的JSON字典是[String:Any]

第五,使用可选绑定来避免运行时错误(崩溃)

func parseJsonData(_ data: Data) -> [Person] {
  var people = [Person]()

  do {
    let jsonResult = try JSONSerialization.jsonObject(with: data, options: JSONSerialization.ReadingOptions.mutableContainers) as! [String:Any]

    // Parse JSON data
    if let jsonPeople = jsonResult["people"] as? [[String:Any]] {
      for jsonPerson in jsonPeople {
        let person = Person()
        person.name = jsonPerson["name"] as! String
        person.id = jsonPerson["id"] as! String

        // children is a key of a person not of the root object !
        if let jsonChildren = jsonPerson["children"] as? [[String:Any]] {
          for jsonChild in jsonChildren {
            let child = Child()
            child.name = jsonChild["name"] as! String
            child.age = jsonChild["age"] as! Int

            person.children.append(child)
          }
        }

        people.append(person)
      }
    }
  } catch {
    print(error)
  }
  return people
}

PS:您将收到另一个错误未定义标识符,因为代码中子循环中的jsonEntrance不存在且childrenpeople的密钥不是根对象。