我有2个json怎么用1个结构解码?

时间:2019-03-02 17:45:03

标签: json swift decode

我有两个相似的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
    }
  ]
}

1 个答案:

答案 0 :(得分: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”:空,

那将是

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)
    }

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