快速解析嵌套对象json

时间:2019-11-03 01:28:07

标签: json swift object nested

根据过去的数据,我如何解析嵌套对象。我想创建一个类User。用户数组将存储所有检索到的数据。解析名称可以正常工作,但是一旦解析到过去的数据,就什么也没有发生。即使我将print(name)放在最后。如果删除三行,则pastdata = object [“ pastdata”]为?字典>,让用户名= pastdata [“用户名”]为?字符串,并让pastPass = pastdata [“ formerpassword”]为? [串。工作正常。有帮助吗?

...代码...

//json
[
  {
    "name": "Jay",
    "pastdata": [
      {
        "username": "lollipopaka",
        "formerpassword": [
          "",
          "def213",
          "j3rds1",
          "ads2fsa"
        ]
      },
      {
        "username": "",
        "formerpassword": []
      },
      {
        "username": "wewunwun123",
        "formerpassword": [
          "dsqwv241s",
          "d323df1ds",
          "sk2d2jo"
        ]
      }
    ]
  }
]


//parse method
    func Parse(jsonObj: [Any]?){

        guard let json = jsonObj
            else{return}

        for firstitem in json{
            guard let object = firstitem as? [String:Any],

            let name = object["name"] as? [String],
             //error starts here
            let pastdata = object["pastdata"] as? Dictionary<String,Array<String>>,
            let username = pastdata["username"] as? String,
            let pastPass = pastdata["formerpassword"] as? [String]
            //if fails
                else{continue}
            }
    }

1 个答案:

答案 0 :(得分:0)

解决此问题的一种方法是创建一个表示json的结构并实现Decodable协议(如果要解码和编码对象,则可以使用Codable)。

定义结构后,只需使用JSONDecoder().decode。以下游乐场项目对此进行了解释:

import Foundation

let sampleJson = """
[
  {
    "name": "Jay",
    "pastdata": [
      {
        "username": "lollipopaka",
        "formerpassword": [
          "abc123",
          "def213",
          "j3rds1",
          "ads2fsa"
        ]
      },
      {
        "username": "deekmcnator",
        "formerpassword": [
          "qk2j30d"
        ]
      },
      {
        "username": "wewunwun123",
        "formerpassword": [
          "dsqwv241s",
          "d323df1ds",
          "sk2d2jo"
        ]
      }
    ]
  },
  {
    "name": "Aaron"
  },
  {
    "name": "Abraham",
    "pastdata": null
  },
  {
    "name": "Lucy",
    "pastdata": [
      {
        "username": "lucy01",
        "formerpassword": [
          "pass01",
          "pass02"
        ]
      },
      {
        "username": "lucy02",
        "formerpassword": [
          "pass03",
          "pass04"
        ]
      }
    ]
  },
  {
    "name": "Moses",
    "pastdata": [
      {
        "username": "moses01",
        "formerpassword": [
        ]
      }
    ]
  }
]
"""

struct PastData: Codable, CustomStringConvertible {
  let username: String?    // Doesn't make sense a null username but
                           // set as optional since ChrisZ asked for
  let formerpassword: [String]? // Optional to handle no former passwords

  var description: String {
    (username ?? "\t\tUsername is null") +
      (formerpassword?.count == 0 ? "\t\tFormerpassword is empty" : formerpassword?.description ?? "\t\tFormerpassword is null")
  }
}

struct UserData : Codable, CustomStringConvertible {
  let name: String
  let pastdata: [PastData]?  // Is optional to take care of no pastdata

  var description: String {
    "\(name)\n" + (pastdata?.count == 0 ? "\tPastdata is empty" : pastdata?.description ?? "\tPastdata is null")
  }
}

func myParse(jsonData: Data) -> [UserData] {
  // If data can't be parse return empty array
  guard let dataDecoded = try? JSONDecoder().decode([UserData]?.self, from: jsonData) else {
    return []
  }
  return dataDecoded
}

if let jsonAsData = sampleJson.data(using: .utf8) {
  let returnedData = myParse(jsonData: jsonAsData)
  returnedData.forEach { // Display each element in  UserData array
    print($0)
  }
}