【问题标题】:I have 2 json how can I decode them with 1 struct?我有 2 个 json 如何用 1 个结构解码它们?
【发布时间】:2019-03-02 17:45:02
【问题描述】:

我有两个相似的 JSON 对象,它们唯一的区别是 joined_user。在第二个joined_user[]。我想用一个结构来解码它们,我该怎么做?

这是我的第一个 JSON 对象

{
  "joined_user":[
    {
      "_id":"5c72c03cd1c32313908845d8"
    },
    {
      "_id":"5c72c14ad1c32313908845db"
    }
  ],
  "allRooms":[
    {
      "Capacity":{
        "Free":10,
        "Total":10
      },
      "Finished":false,
      "Pic":"http://192.168.1.101:2525/icon.png",
      "_id":"5c72bf3fd1c32313908845d6",
      "Coin_input":10,
      "Award_money":100000,
      "Award_coin":100,
      "Match_time":"1551551483",
      "Winner_number":1
    },
    {
      "Capacity":{
        "Free":20,
        "Total":20
      },
      "Finished":false,
      "Pic":"http://192.168.1.101:2525/icon.png",
      "_id":"5c72bf58d1c32313908845d7",
      "Coin_input":20,
      "Award_money":200000,
      "Award_coin":200,
      "Match_time":"1551551483",
      "Winner_number":1
    },
    {
      "Capacity":{
        "Free":9,
        "Total":10
      },
      "Finished":false,
      "Pic":"http://192.168.1.101:2525/icon.png",
      "_id":"5c72c03cd1c32313908845d8",
      "Coin_input":100,
      "Award_money":100000,
      "Award_coin":1000,
      "Match_time":"1551551483",
      "Winner_number":1
    },
    {
      "Capacity":{
        "Free":20,
        "Total":20
      },
      "Finished":false,
      "Pic":"http://192.168.1.101:2525/icon.png",
      "_id":"5c72c066d1c32313908845d9",
      "Coin_input":101,
      "Award_money":200000,
      "Award_coin":2000,
      "Match_time":"1551551483",
      "Winner_number":1
    },
    {
      "Capacity":{
        "Free":9209269,
        "Total":10000000
      },
      "Finished":true,
      "Pic":"http://192.168.1.101:2525/icon.png",
      "_id":"5c72c14ad1c32313908845db",
      "Coin_input":12,
      "Award_money":50000,
      "Award_coin":500,
      "Match_time":"1551540600",
      "Winner_number":1
    }
  ]
}

这是我的第二个 JSON 对象

{
  "joined_user":"[]",
  "allRooms":[
    {
      "Capacity":{
        "Free":44,
        "Total":100
      },
      "Finished":false,
      "Pic":"www",
      "_id":"5c73c1666f39db1de8977fd9",
      "Coin_input":10,
      "Award_money":10000,
      "Award_coin":1000,
      "Match_time":"9",
      "Winner_number":2
    },
    {
      "Capacity":{
        "Free":9999,
        "Total":9999
      },
      "Finished":false,
      "Pic":"129",
      "_id":"5c7535a56f39db1de897802d",
      "Coin_input":9,
      "Award_money":99999,
      "Award_coin":999,
      "Match_time":"9",
      "Winner_number":9
    },
    {
      "Capacity":{
        "Free":9999,
        "Total":9999
      },
      "Finished":false,
      "Pic":"129",
      "_id":"5c7535a66f39db1de897802e",
      "Coin_input":9,
      "Award_money":99999,
      "Award_coin":999,
      "Match_time":"9",
      "Winner_number":9
    },
    {
      "Capacity":{
        "Free":9999,
        "Total":9999
      },
      "Finished":false,
      "Pic":"129",
      "_id":"5c7535a86f39db1de897802f",
      "Coin_input":9,
      "Award_money":99999,
      "Award_coin":999,
      "Match_time":"9",
      "Winner_number":9
    }
  ]
}

【问题讨论】:

  • 在你的结构中使joineduser可选

标签: json swift decode


【解决方案1】:

这是一个用户模型数组

"joined_user": [
   {
    "_id": "5c72c03cd1c32313908845d8"
  },
  {
    "_id": "5c72c14ad1c32313908845db"
  }
]

这是一个字符串

"joined_user":"[]"

要同时阅读,您需要

struct Root: Codable {
    let joinedUser: CombinedRes
    let allRooms: [AllRoom]

    enum CodingKeys: String, CodingKey {
        case joinedUser = "joined_user"
        case allRooms
    }
}

struct AllRoom: Codable {
    let capacity: Capacity
    let finished: Bool
    let pic, id: String
    let coinInput, awardMoney, awardCoin: Int
    let matchTime: String
    let winnerNumber: Int

    enum CodingKeys: String, CodingKey {
        case capacity = "Capacity"
        case finished = "Finished"
        case pic = "Pic"
        case id = "_id"
        case coinInput = "Coin_input"
        case awardMoney = "Award_money"
        case awardCoin = "Award_coin"
        case matchTime = "Match_time"
        case winnerNumber = "Winner_number"
    }
}

struct Capacity: Codable {
    let free, total: Int

    enum CodingKeys: String, CodingKey {
        case free = "Free"
        case total = "Total"
    }
}

enum CombinedRes: Codable {
    case joinedUserElementArray([JoinedUserElement])
    case string(String)

    init(from decoder: Decoder) throws {
        let container = try decoder.singleValueContainer()
        if let x = try? container.decode([JoinedUserElement].self) {
            self = .joinedUserElementArray(x)
            return
        }
        if let x = try? container.decode(String.self) {
            self = .string(x)
            return
        }
        throw DecodingError.typeMismatch(CombinedRes.self, DecodingError.Context(codingPath: decoder.codingPath, debugDescription: "Wrong type for CombinedRes"))
    }

    func encode(to encoder: Encoder) throws {
        var container = encoder.singleValueContainer()
        switch self {
        case .joinedUserElementArray(let x):
            try container.encode(x)
        case .string(let x):
            try container.encode(x)
        }
    }
}

struct JoinedUserElement: Codable {
    let id: String

    enum CodingKeys: String, CodingKey {
        case id = "_id"
    }
}

但如果你能改变这个

"joined_user": "[]",

"joined_user": [],

那就是

struct Root: Codable {
    let joinedUser: [JoinedUserElement]
    let allRooms: [AllRoom]

    enum CodingKeys: String, CodingKey {
        case joinedUser = "joined_user"
        case allRooms
    }
}

"joined_user":null,

那就是

struct Root: Codable {
    let joinedUser: [JoinedUserElement]?
    let allRooms: [AllRoom]

    enum CodingKeys: String, CodingKey {
        case joinedUser = "joined_user"
        case allRooms
    }
}

    do {
        let res = try JSONDecoder().decode(Root.self,from:data)
        switch(res.joinedUser) {
        case  .joinedUserElementArray( let arr) :
                let ids = arr.map { $0.id }
                print(ids)
        case .string(let str) :
            break
        default:
            break
        }
    }
    catch {
        print(error)
    }

您还可以在Root 内编写自定义init,如果接收到的值为字符串,则将空分配给数组

【讨论】:

  • 我如何在 joienduser 中打印 id ??
  • 如果您按照上述方式保留字符串和数组模型,那么您需要一个 Switch 并将它们打印在 .joinedUserElementArray 案例中
  • 你能帮我写代码吗?我想把 id 放在数组中
  • @Sh_Khan 已经回答得非常好。你应该首先接受他的回答。请注意,StackOverflow 是一个网站,它可以帮助您找到解决您正在努力解决的问题的解决方案(并表现出一些努力自己解决问题的意愿)。简单地要求别人“做你的工作”不会产生很好的结果,特别是如果你不能具体地提出你的要求。请根据您所学的内容修改您的问题,并在必要时再问一个问题。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-11-01
  • 1970-01-01
  • 2014-07-12
  • 1970-01-01
相关资源
最近更新 更多