Как отобразить JSON данные на tableView

swift
json
tableview

#1

Всем привет! У меня получилось выгрузить JSON по соответствующему адерсу (линк в коде), но никак не получается отобразить данные из вложенного массива JSON на tableVIew. Сам линк на API - https://kudago.com/public-api/v1.4/events/?location=msk&is_free=1&fields=id,title,images
Вот структуры:

struct EventsMain : Codable {
    let count : Int?
    let next : String?
    let previous : String?
    let results : [Results]?

    enum CodingKeys: String, CodingKey {

        case count = "count"
        case next = "next"
        case previous = "previous"
        case results = "results"
    }

    init(from decoder: Decoder) throws {
        let values = try decoder.container(keyedBy: CodingKeys.self)
        count = try values.decodeIfPresent(Int.self, forKey: .count)
        next = try values.decodeIfPresent(String.self, forKey: .next)
        previous = try values.decodeIfPresent(String.self, forKey: .previous)
        results = try values.decodeIfPresent([Results].self, forKey: .results)
    }

}

Ниже

struct Results : Codable {
    let id : Int?
    let title : String?
    let images : [Images]?

    enum CodingKeys: String, CodingKey {

        case id = "id"
        case title = "title"
        case images = "images"
    }

    init(from decoder: Decoder) throws {
        let values = try decoder.container(keyedBy: CodingKeys.self)
        id = try values.decodeIfPresent(Int.self, forKey: .id)
        title = try values.decodeIfPresent(String.self, forKey: .title)
        images = try values.decodeIfPresent([Images].self, forKey: .images)
    }

}

Ниже

struct Images : Codable {
    let image : String?
    let source : Source?

    enum CodingKeys: String, CodingKey {

        case image = "image"
        case source
    }

    init(from decoder: Decoder) throws {
        let values = try decoder.container(keyedBy: CodingKeys.self)
        image = try values.decodeIfPresent(String.self, forKey: .image)
        source = try Source(from: decoder)
    }

}

И последняя

struct Source : Codable {
    let name : String?
    let link : String?

    enum CodingKeys: String, CodingKey {

        case name = "name"
        case link = "link"
    }

    init(from decoder: Decoder) throws {
        let values = try decoder.container(keyedBy: CodingKeys.self)
        name = try values.decodeIfPresent(String.self, forKey: .name)
        link = try values.decodeIfPresent(String.self, forKey: .link)
    }

}

Далее, сам класс ViewController, в котором находится tableView

class ViewController: UIViewController, UITableViewDelegate, UITableViewDataSource {


    @IBOutlet weak var tableView: UITableView!

    var results: EventsMain?

    override func viewDidLoad() {
        super.viewDidLoad()

        downloadJSON {

            self.tableView.reloadData()
        }


        self.tableView.delegate = self
        self.tableView.dataSource = self

    }

    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
        // Dispose of any resources that can be recreated.
    }


     func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return
    }

     func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let cell = tableView.dequeueReusableCell(withIdentifier: "EventCell", for: indexPath) as? EventsTableViewCell



        return cell!
    }


func downloadJSON(completed: @escaping () -> ()) {
    let url = URL(string: "https://kudago.com/public-api/v1.4/events/?location=msk&is_free=1&fields=id,title,images")
    URLSession.shared.dataTask(with: url!) { (data, response, error) in
        if error == nil {
            do {
                let task = try JSONDecoder().decode(EventsMain.self, from: data!)

                DispatchQueue.main.async {
                    completed()
                print(task)
                    self.results = task
                }
            } catch {
                print("JSON Error")
            }
        }

        }.resume()
}

}

На tableView я хочу отобразить значение ключа title, который находится в структуре Results. Как это сделать?

Заранее, огромное спасибо :slight_smile:


#2

Cоздайте переменную в классе с TableView

var eventsMain = EventsMain

В методе downloadJSON:

let task = try JSONDecoder().decode(EventsMain.self, from: data!)
 self.eventsMain = task

Потом через переменную task доставайте значение title в методах tableView.


#3

Окей, спасибо большое!
Отпишу по результатам, как сделаю.


#4

Немного неясно… Как мне выцепить task и что прописывать вcellForRow at IndexPath? task не видит в коде, кроме в самом методе downloadJSON


#5
class ViewController: UIViewcontroller, TableDataSource, TableDelegate {
   var eventsMain: EventsMain?
   ...
   func downloadJSON() {
      ...
      let task = try JSONDecoder().decode(EventsMain.self, from: data!)
      self.eventsMain = task
      ...
   }

   func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return eventsMain?.count ?? 0 или eventsMain?.results?.count ?? 0
    }

   func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let cell = tableView.dequeueReusableCell(withIdentifier: "EventCell", for: indexPath) as! EventsTableViewCell
        if let result = eventsMain?.results?[indexPath.row] {
           cell.titleLabel.text = result.title
        }
        else {
            return UITableViewCell()        
        }

        return cell
    }
}

#7

Спасибо большое! Все запустилось :slight_smile: