'How do I convert JSON with variable variable names into swift object?
I am working on a project with an API which gives me a JSON Object with some data in a variable. But the name of the variable under which the data is provided changes from day to day. For example today the name will be 285 and tomorrow it‘ll be 286. How can I convert this into a Swift object? I've already written some code so here it is:
Getting data part:
func getData(){
let semaphore = DispatchSemaphore.init(value: 0)
let url = URL(string: URL_STRING)!
var request = URLRequest(url: url)
request.httpMethod = "GET"
session.dataTask(with: request) { (dat, res, err) in
print("Anfrage gestellt")
guard let data = dat else {
print("no Data")
return
}
guard let resp = res else {
print("No Response ")
return
}
if let error = err {
print("Error: \(error)")
return
}
do{
let decodedData = try self.decoder.decode(Report.self, from: data)
print(decodedData)
} catch {
print("Data decode failed \(error)")
}
semaphore.signal()
}.resume()
semaphore.wait()
return
}
The object in which it will be converted:
class Report: Codable{
var keys: [String] = []
var latest: String?
let s: S
init(keys: [String], s: S){
self.keys = keys
self.s = s
latest = keys[keys.count - 1]
}
enum CodingKeys: String, CodingKey{
case s = "286"
}
}
The JSON Object:
{
"285": {
"AT": {
"av": -72.1,
"ct": 113986,
"mn": -100.813,
"mx": -27.115
},
"First_UTC": "2019-09-15T01:13:15Z",
"HWS": {
"av": 4.347,
"ct": 54297,
"mn": 0.20600000000000002,
"mx": 21.272
},
"Last_UTC": "2019-09-16T01:52:49Z",
"PRE": {
"av": 742.003,
"ct": 89613,
"mn": 723.2129,
"mx": 757.8722
},
"Season": "spring",
"WD": {
"1": {
"compass_degrees": 22.5,
"compass_point": "NNE",
"compass_right": 0.382683432365,
"compass_up": 0.923879532511,
"ct": 1
},
"10": {
"compass_degrees": 225.0,
"compass_point": "SW",
"compass_right": -0.707106781187,
"compass_up": -0.707106781187,
"ct": 6973
},
"11": {
"compass_degrees": 247.5,
"compass_point": "WSW",
"compass_right": -0.923879532511,
"compass_up": -0.382683432365,
"ct": 3196
},
"12": {
"compass_degrees": 270.0,
"compass_point": "W",
"compass_right": -1.0,
"compass_up": -0.0,
"ct": 3066
},
"3": {
"compass_degrees": 67.5,
"compass_point": "ENE",
"compass_right": 0.923879532511,
"compass_up": 0.382683432365,
"ct": 131
},
"5": {
"compass_degrees": 112.5,
"compass_point": "ESE",
"compass_right": 0.923879532511,
"compass_up": -0.382683432365,
"ct": 680
},
"6": {
"compass_degrees": 135.0,
"compass_point": "SE",
"compass_right": 0.707106781187,
"compass_up": -0.707106781187,
"ct": 9405
},
"7": {
"compass_degrees": 157.5,
"compass_point": "SSE",
"compass_right": 0.382683432365,
"compass_up": -0.923879532511,
"ct": 8813
},
"8": {
"compass_degrees": 180.0,
"compass_point": "S",
"compass_right": 0.0,
"compass_up": -1.0,
"ct": 8231
},
"9": {
"compass_degrees": 202.5,
"compass_point": "SSW",
"compass_right": -0.382683432365,
"compass_up": -0.923879532511,
"ct": 13801
},
"most_common": {
"compass_degrees": 202.5,
"compass_point": "SSW",
"compass_right": -0.382683432365,
"compass_up": -0.923879532511,
"ct": 13801
}
}
},
"sol_keys": [
"285"
]
}
Thanks for your help
Solution 1:[1]
As mentioned you can decode this as a dictionary, first define a struct for the data you want to decode
struct ReportData: Decodable {
let at: SomeData
let firstUTC: Date
let hws: SomeData
//...
}
and then decode it as
let decodedData = try self.decoder.decode([String:ReportData].self, from: data)
to find the right key in the dictionary it looks like you can use sol_keys
if let keys = decodedData ["sol_keys"] {
for key in keys {
let report = decodeData[key]
//...
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
Solution | Source |
---|---|
Solution 1 | Joakim Danielson |