Во-первых, как заметил @Benhamine, вы должны начать с чистой архитектуры и отобразить свой JSON в класс безопасного типа.
Шаг 1: Кодируемые типы
Позволяет определить структуру, которая представляет наш JSON, чтобы мы могли лучше использовать его в нашем приложении. JSON - это то, что мы никогда не хотим распространять в нашем приложении. Давайте лучше обойдем что-то четко определенное и задокументированное, поэтому нам не нужно будет насильно разворачивать и вылетать из нашего приложения.
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
}
}
Шаг 2: Разбор
Разбор с использованием Codable очень прост. Приведенный ниже код покажет, как мы конвертируем его в JSON, а также как можно получить сумму значений с плавающей запятой.
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)
}
Шаг 3: интегрировать
Теперь у нас есть строительные блоки, которые нам нужны для получения этой информации, поэтому давайте подключим ее к вашему коду, начав с того, что мы хотим , чтобы наш код выглядел.
/// 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
}
Обратите внимание, как в приведенном выше коде я не выполняю любое JSON-декодирование при снятии очереди с ячейки. В идеале это должно быть сделано, когда мы получаем наш JSON и конвертируем его в наши типы.
Шаг 4: Рефакторинг
Важная часть любого кода должна содержать некоторое отражение в написанном нами коде и обдумывать, как его можно реорганизовать.
В нашем примере выше мы, вероятно, могли бы жестко закодировать итоги на контроллере или создать собственную структуру данных, которая сделает это за нас, когда мы проанализируем JSON. Всегда ли мы хотим вычислять итоги вручную, если нам всегда нужна эта сумма? У нас может быть специальная функция для вычисления или просто в нашей логике декодирования JSON.
В любом случае, идея в том, что мы всегда должны смотреть на то, что пишем, и спрашивать, как это можно улучшить