【问题标题】:Parsing Nested Object json in swift快速解析嵌套对象 json
【发布时间】:2019-11-03 01:28:07
【问题描述】:

在过去的数据中,我如何解析嵌套对象。我想创建一个类用户。一个用户数组将存储所有检索到的数据。解析名称工作得很好,但一旦到达过去数据,什么都不会发生。即使我把 print(name) 放在最后。如果我删除这三行 let pastdata = object["pastdata"] as? Dictionary>,let username = pastdata["username"] as?字符串,并让 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}
            }
    }

【问题讨论】:

    标签: json swift object nested


    【解决方案1】:

    解决此问题的一种方法是创建一个表示 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)
      }
    }
    

    【讨论】:

    • 有一些空数据,所以建议我使用保护。抱歉,我是 swift 新手
    • 哪些数据可以为空?您可以使用可选项,例如,如果用户名不存在,您可以将其定义为 String?,因此如果用户名带有 null 值,则可选项将包含 nil。你能提供一个带有空数据的示例 JSON 吗?我可以更改代码以考虑软管案例。
    • 如果formerpassword 为空,因为是一个数组就没有问题。
    • 将一些更改为空。你能用我做过的格式编码吗?我正在尝试保存检索到的数据。并提供一些 cmet 来解释这个过程。
    • @Chris Z 我刚刚更新了处理结构中几个字段中的空值和空值的答案。
    猜你喜欢
    • 2019-03-22
    • 1970-01-01
    • 2020-02-22
    • 2023-03-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-04-23
    • 1970-01-01
    相关资源
    最近更新 更多