【问题标题】:populate tableview cell from complex api json using swift使用 swift 从复杂的 api json 填充 tableview 单元格
【发布时间】:2019-12-22 08:09:35
【问题描述】:

我正在尝试解析 API JSON 并将其显示在 UITableView 中,但问题是我无法访问此 API 中的所有数组。

struct RootResults: Codable { 
    var results: [results] 
} 

// MARK: - results 
struct results: Codable { 
    var container_number: String? 
    var commodities: [commodities] 
} 

// MARK: - commodities 
struct commodities: Codable { 
    var commodity_name_en: String? 
    var varieties: [varieties] 
} 

// MARK: - varieties 
struct varieties: Codable { 
    var variety_name_en: String? 
    var variety_name_ar: String? 
} 

import UIKit

class ViewController: UIViewController {

    @IBOutlet var resultsTable: UITableView!
    override func viewDidLoad() {
        super.viewDidLoad()
        abuseedoAPIget() 
    }

    var arrData = [results]()
    var arrResults = [commodities]()
    func abuseedoAPIget(){
        let urlJSON = "http://abuseedotrading.com/apps/api/acp/?key=4ea1e08dd9ab329bbdaa9e5b42939c04&query=list_containers"
            guard let url = URL(string: urlJSON) else {return}
            URLSession.shared.dataTask(with: url) { (data, response, error) in
                guard let data = data else {return}
                guard error == nil else {return}
                do {
                    let decoder = JSONDecoder()
                    let APIResponse = try decoder.decode(RootResults.self, from: data)
                    self.arrData = APIResponse.results
                    DispatchQueue.main.async{
                        self.resultsTable.reloadData()
                    }

                } catch let error {
                    print("Failed to decode JSON:", error)
                }
            }.resume()
        }

}

extension ViewController: UITableViewDelegate, UITableViewDataSource{

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


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

        let dataa = arrData[indexPath.row]
        cell.conLabel.text = dataa.container_number
       cell.comLabel.text = dataa.commodity_name_en
        return cell
    }

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

        return UITableView.automaticDimension
    }
}

【问题讨论】:

  • 在您的日志中提供更多信息。它说什么?你有空指针异常吗?您是否在信息列表中添加了 AppTransportSecurity?
  • RootResults 一个或多个属性类型不匹配
  • 请添加结构并详细说明 what 到底是什么不起作用。
  • import Foundation // MARK: - RootResults struct RootResults: Codable { var results: [results] } // MARK: - results struct results: Codable { var container_number: String? var 商品:[commodities] } // MARK: - 商品结构商品:可编码 { var 商品名称:字符串? var 品种:[品种] } // MARK:-品种结构品种:可编码{ var品种名称:字符串?变种名称_ar:字符串? }
  • 我可以访问结果数组,但我不能访问商品数组

标签: arrays json swift


【解决方案1】:

为了让 Swift 能够将 JSON 响应解码为对象,您需要在 Swift 中使用对象定义类似的结构。

您的RootResults 对象需要实现Codable 协议并表示JSON 结构。

在返回的 JSON 的一部分下面:

{
  "status": 200,
  "runtime": 1.7315270900726,
  "results_count": 13,
  "results": [
    {
      "container_id": 36473,
      "container_number": "MMAU1163814",
      "shipment_id": 17359,
    }
}

RootResults 看起来像这样:

struct RootResults: Codable {
  let status: Int
  let runtime: Float
  let results_count: 13
  let results: [Container]
}

struct Container: Codable {
  let container_id: Int
  let container_number: String
  let shipment_id: Int
}

更多关于 Swift Codable 的信息

Swift codable

SO question about

在函数tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) 中,您正在访问不同级别的数据。 从results 检索对象时可以访问container_number 属性。 commodity_name_en 是更深的“级别”,是 commodities 数组的一部分。要访问 commodities -array 中的第一项,请尝试以下操作:

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

        let dataa = arrData[indexPath.row]
        cell.conLabel.text = dataa.container_number
       cell.comLabel.text = dataa.commodities[0].commodity_name_en
        return cell
    }

正如 Vadian 所提到的,在 Swift 中,类型(结构、类、枚举)通常以大写字母开头。查看struct and classes 文档

【讨论】:

  • 非常感谢 Eelco,现在我可以访问我的 API 中的所有级别。最后一个提示正常工作。
猜你喜欢
  • 2016-06-01
  • 1970-01-01
  • 2016-01-15
  • 1970-01-01
  • 1970-01-01
  • 2016-01-24
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多