I'm using TMDB api and fetching tv show seasons, but seasons I get back are not inside array, but as objects with names: season/1
, season/2
. I need to be able to parse tv show with any number of seasons
Is there a way I can convert this to array without worring about how many seasons does the show have?
struct Result: Codable {
var season1: Season?
var season2: Season?
var id: Int?
enum CodingKeys: String, CodingKey {
case season1
case season2
case id
}
}
struct Season: Codable {
var id: Int?
enum CodingKeys: String, CodingKey {
case id
}
}
{
"id" : 1234,
"season/1": {
"id": 1234
},
"season/2": {
"id": 12345
}
}
EDIT: Found a solution in dynamic coding keys
private struct DynamicCodingKeys: CodingKey {
var stringValue: String
init?(stringValue: String) {
self.stringValue = stringValue
}
var intValue: Int?
init?(intValue: Int) {
return nil
}
}
init(from decoder: Decoder) throws {
let container = try decoder.container(keyedBy: DynamicCodingKeys.self)
var tempArray = [TestSeason]()
for key in container.allKeys {
if key.stringValue.contains("season/") {
let decodedObject = try container.decode(TestSeason.self, forKey: DynamicCodingKeys(stringValue: key.stringValue)!)
tempArray.append(decodedObject)
} else {
print("does not contain season \(key.stringValue)")
}
}
season = tempArray
}
CodePudding user response:
You're getting back a Dictionary
, which you can access directly without using your Results
struct. The dictionary probably provides a more flexible way of accessing the data than an array, but can also easily be converted to an Array.
As you haven't stated how you'd like the output, the below will convert them to an array of tuples, where each tuple is (season, id)
let data = json.data(using: .utf8)!
let decoder = JSONDecoder()
do {
let results = try decoder.decode([String:Season].self, from: data)
.map{($0.key, $0.value.id )}
print(results) // [("season/2", 12345), ("season/1", 1234)]
} catch {
print(error)
}
Edit: You also don't need the CodingKeys
in Season
as it can be inferred from the properties. All you need is
struct Season: Codable {
let id: Int
}