Парсинг JSON и работа с массивом для вывода в TableView

swift
array
uitableview
json

#1

Добрый день!
Подскажите пожалуйста новичку по следующему вопросу:

  1. Почему в мой объявленный массив в классе var tableArray = [BikeWelcome] () данные не приходят после обработки функции по парсингу и декодированию приходящего Json в методе viewDidLoad().
  2. Внутри метода userApiJsonCodable2 () массив данных self.tableArray.append(model) заполняется данными корректно и содержит декодируемую информацию переменной model.
  3. Как улучшить или модернизировать мой код, для того что бы можно было работать с объявленным массивом var tableArray = [BikeWelcome] () в классе после обработки метода serApiJsonCodable2 () размещенного в viewDidLoad() ?
    Т.е. я хочу декодировать и распарсить данные json-а и положить их в массив для последующей работы внутри класса и обращения разных к нему функций например тот же
    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
    return tableArray[0].bikesCatalog.count
    }

Собственно сам код:

import UIKit

class ViewController: UIViewController, UITableViewDataSource, UITableViewDelegate {

var tableArray = [BikeWelcome] ()

@IBOutlet weak var bikeTable: UITableView!


override func viewDidLoad() {
    super.viewDidLoad()
   
    userApiJsonCodable2()
   
    self.bikeTable.delegate = self
    self.bikeTable.dataSource = self
   
    print(self.tableArray)
   
}

func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
    //return tableArray[0].bikesCatalog.count
    return 3
}

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
   
    if let cell = bikeTable.dequeueReusableCell(withIdentifier: "bikeCell", for: indexPath) as? BikeCell {
       return cell
    }
    return UITableViewCell()
   

}

func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat
{
    return 100.0
}



func userApiJsonCodable2 () {
   
    guard let url = URL(string: "https://static.upstarts.work/test_task/bikes_catalog/bikes_164Sf3fqye4u.json") else {return}
    let task = URLSession.shared.dataTask(with: url) { (data, response, error) in
        guard let dataResponse = data,
            error == nil else {
                print(error?.localizedDescription ?? "Response Error")
                return }
       
        do {
            //here dataResponse received from a network request
            let decoder = JSONDecoder()
            let model = try decoder.decode(BikeWelcome.self, from: dataResponse) //Decode JSON Response Data
            //tableArray = [try decoder.decode(BikeWelcome.self, from: dataResponse)]
           
            self.tableArray.append(model)
            print("COUNT \(self.tableArray[0].bikesCatalog.count)")
            print("---------Codable---------")
        } catch let parsingError {
            print("Error", parsingError)
        }
    }
    task.resume()
}

}


#2
  1. не вижу обновление таблицы после self.tableArray.append(model)
  2. перенесите из viewDidLoad во viewWillAppear

#3

Вы похоже еще не поняли что значит асинхронный код.
Вы принт не там делаете.
По коду у вас все правильно, не хватает лишь обновления таблицы после получения данных.


#4

Если я все правильно понимаю, то

  1. все приходит, только позже чем срабатывает viewDidLoad(), поэтому когда принтите выводит пустой массив

  2. (только лучше не обращаться по индексам на прямую, используйте .first вместо [0], либо делайте проверку на выход за пределы массива)

Как сказал Ivan411 вам не хватает tableView.reloadData() после добавления модели в массив