HI All,
I have litterally been trying this for hours and I cannot get it to work! I am hopefull someone can assist. Appologies its a little messy as I have been messing around with it so much. I have an array in JSON, which I want to put into an array in Swift. It normally comes from a server, but I have tested it using a string to try and find the error. I did get it to work with a single JSON object earlier, but now there is an array, no luck.
I don't get any errors, the program runs, but there is no data in tableData from the decoder. The rowcount is 0 and the output of print(tableData) is Optional(WellandPowerLive.StockByWarehouseResponse(StockByWarehouse: []))
If its simpler to achieve, I could drop the top level, as i am writing the server side also, if the JSON was just like this does it make it easier?:
JSONString = "[
{\"ItemCode\":\"Test\",\"OnHand\":3,\"IsCommited\":5,\"OnOrder\":5},
{\"ItemCode\":\"Test2\",\"OnHand\":3,\"IsCommited\":2,\"OnOrder\":1}
]"
here is the current code. TIA for all assistance.
struct StockByWarehouseResponse: Codable {
let StockByWarehouse: [SAPB1_StockItem] = Array()
}
struct SAPB1_StockItem: Codable {
let WhsCode: String
let ItemCode: String
let OnHand: Decimal
let IsCommited: Decimal
let OnOrder: Decimal
}
JSONString = "{\"StockByWarehouse\":[{\"ItemCode\":\"Test\",\"OnHand\":3,\"IsCommited\":5,\"OnOrder\":5}, {\"ItemCode\":\"Test2\",\"OnHand\":3,\"IsCommited\":2,\"OnOrder\":1}}"
print(JSONString)
let jsonData = JSONString.data(using: .utf8)!
let decoder = JSONDecoder()
tableData = try! decoder.decode(StockByWarehouseResponse.self, from: jsonData)
print(tableData)
print("Rows in array: \(tableData?.StockByWarehouse.count)")
You have multiple things wrong here, but as you say some of that just comes from trying things.
I think the main problem is that you've declared the "StockByWarehouse" property with 'let', not 'var', which means the decoded array cannot be assigned to it. This is arguable a bug in Decodable conformance, I suppose, since the decoding code probably shouldn't be synthesized if it won't work. Also, you didn't supply values for the "WhsCode" property.
Here's a slightly revised version that works in a playground:
let JSONString = """
{"StockByWarehouse":
[
{"WhsCode":"A","ItemCode":"Test","OnHand":3,"IsCommited":5,"OnOrder":5},
{"WhsCode":"B","ItemCode":"Test2","OnHand":3,"IsCommited":2,"OnOrder":1}
]
}
"""
print(JSONString)
let jsonData = JSONString.data(using: .utf8)!
do {
let decoder = JSONDecoder()
let tableData = try decoder.decode(StockByWarehouseResponse.self, from: jsonData)
print(tableData)
print("Rows in array: \(tableData.StockByWarehouse.count)")
}
catch {
print (error)
}
It makes things a bit easier if you use a multi-line literal for the string, so you don't have to escape everything. Catching errors is also a good idea, because the error message will tell you where in the decoding it failed.
>> If its simpler to achieve, I could drop the top level
It's up to you. If you do, you would replace the line that does the decoding with this:
let tableData = try decoder.decode([SAPB1_StockItem].self, from: jsonData)
That decodes an array at the top level.