First, as @Benhamine pointed out you should start with a clean architecture and map your JSON into a type safe class.
Step 1: Codable Types
Lets define a structure that represents our JSON so we can better consume it in our App. JSON is something we never want to pass around our App. Lets rather pass around something well-defined and documented so we have no need to do any force unwraps and crash our App.
struct JSONResponse: Codable {
enum CodingKeys: String, CodingKey {
case data
}
let data: Data
}
extension JSONResponse {
struct Data: Codable {
enum CodingKeys: String, CodingKey {
case results = "result"
}
let results: [Result]
}
}
extension JSONResponse.Data {
struct Result: Codable {
let name: String
let winners: [Winner]
enum CodingKeys: String, CodingKey {
case winners = "response"
case name
}
}
}
extension JSONResponse.Data.Result {
struct Winner: Codable {
let name: String
let prize: String
}
}
Step 2: Parsing
Parsing using Codable is super simple. The code below will show how we convert it into JSON and also how one could go about getting the sum of the float values.
do {
let o: JSONResponse = try JSONDecoder().decode(JSONResponse.self, from: jsonData)
let floatValues = o.data.results.flatMap({ $0.winners }).compactMap({ Float($0.prize) })
floatValues.reduce(0, +)
print(floatValues)
} catch let e {
print(e)
}
Step 3: Integrate
We now have the building blocks we need to get this information so let's hook it up to your code by starting with what we want our code to look like.
/// We store our main data type for easy reference
var resultsBySection: [Result]
func tableView(_ tableView: UITableView, viewForHeaderInSection section: Int) -> UIView?
{
let header = tableView.dequeueReusableHeaderFooterView(withIdentifier: cellReuseIdentifier) as! OverallHeaderCell
let currentResults = resultsBySection[section]
let prizeTotals = currentResults.flatMap({ $0.winners }).compactMap({ Float($0.prize) })
let totalPriceMoney = prizeTotals.reduce(0, +)
header.textL[0].text = currentResults.name
header.textL[3].text = "\(String(describing: totalPriceMoney))"
return header
}
Notice how in the above code I do not do any JSON decoding in cell dequeueing. Ideally that should be done when we retrieve our JSON and convert it to our types.
Step 4: Refactor
An essential piece of any code experience should contain some reflection into the code we have written and consider how it could be refactored.
In our example above we could probably hardcode the totals onto the controller or create a custom data structure that will do this for us when we parse JSON. Do we always want to manually calculate the totals if we always need this total? We could have a custom function to do the calculation or just do it in our JSON decoding logic.
Anyways, the idea is that we should always look at what we are writing and question how it could be improved