如何使用从服务器接收到的 JSON 数据更新 UI?

How can I update UI using JSON data that I'm receiving from the server?

我正在使用 Swift Codable Protocol 并接收 JSON 我需要放入我的标签和图像中的数据,但是当我 运行 应用程序。

这是我的代码的样子

import UIKit

struct OfferList: Codable {
    let data: [Int: CarItems]?
    let status: String?
    let count: Int? }

struct CarItems: Codable {

    let id: String?
    let image: URL?
    let manufacturer: String?
    let model: String?
    let price_net: Int?
    let price_old: Int?
    let price_gross: Int?
    let power_kw: String?
    let power_ps: String?
    let milage: String?
    let fueltype: String? }

class OfferVC: UIViewController {

    @IBOutlet weak var tableView: UITableView!

    var viewModels = [CarItems]() {
        didSet {
            self.tableView.reloadData()
        }
    }

    override func viewDidLoad() {
        super.viewDidLoad()

        let urlString = "http://grandex.de/api/v1/de/offers"
        guard let url = URL(string: urlString) else { return }

        URLSession.shared.dataTask(with: url) { (data, response, err) in
            guard let data = data else { return }
            guard err == nil else { return }

            do {
                let array: Any = try JSONSerialization.jsonObject(with: data, options: [.allowFragments])
                print(array)
                if let objects = try JSONDecoder().decode(OfferList.self, from: data).data {
                    objects.forEach({
                        print([=12=])
                        self.viewModels.append()

                        DispatchQueue.main.async {
                            self.tableView.reloadData()
                        }
                    })
                }
            } catch let jsonErr {
                print(jsonErr)
            }
        }.resume()
    } }

extension OfferVC: UITableViewDelegate, UITableViewDataSource {

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

    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {

        let cell = tableView.dequeueReusableCell(withIdentifier: "id") as! Cell
        let vm = viewModels[indexPath.row]
        cell.update(with: vm)
        return cell
    }

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

class Cell: UITableViewCell {

    @IBOutlet weak var carImage: UIImageView?
    @IBOutlet weak var title: UILabel?
    @IBOutlet weak var fuelType: UILabel?

    func update(with item: CarItems) {
        title?.text = item.manufacturer
        fuelType?.text = item.fueltype
    } }

我希望它能更改我的标签,但在模拟器中 table 视图是空的。 请指教我做错了什么。 还有人可以告诉我如何使用 JSON 数据更新图像吗? 任何帮助将非常感激!提前致谢!!

您需要在 viewDid load 中添加以下代码行。

tableView.dataSource = self
tableView.delegate = self

希望对您有所帮助。

结构中有两个主要错误,data[CarItems]priceNetDouble

你必须得到错误

Type 'Dictionary' mismatch: Expected to decode Dictionary but found an array instead.

声明所有结构成员 non-optional 并将它们命名为 camelCased

struct OfferList: Decodable {
    let data: [CarItems]
    let status: String
    let count: Int
}

struct CarItems: Decodable {

    let id: String
    let image: URL
    let manufacturer: String
    let model: String
    let priceNet: Double
    let priceOld: Int
    let priceGross: Int
    let powerKw: String
    let powerPs: String
    let milage: String
    let fueltype: String
}

声明没有属性观察者的数据源数组

var viewModels = [CarItems]()

解码JSON

URLSession.shared.dataTask(with: url) { (data, _, error) in
      if let error = error { print(error); return }     

      do {   
         let decoder = JSONDecoder()
         decoder.keyDecodingStrategy = .convertFromSnakeCase
         let result = try decoder.decode(OfferList.self, from: data!)
         self.viewModels = result.data
         DispatchQueue.main.async {
             self.tableView.reloadData()
         }          
      } catch {
          print(error)
      }
}.resume()

确保表视图的 datasourcedelegate 已连接到 Interface Builder 中首选的视图控制器。

在 table 视图数据源和委托函数中添加断点,以确保有来自服务器的预期数据。另外,我看到在您的 CustomCell 中,插座属于可选类型,但不应该是。另外检查 update(with item: CarItems) 函数以使用断点查看标签和预期值是否存在。