【问题标题】:Display array elements from JSON in the tableview在 tableview 中显示来自 JSON 的数组元素
【发布时间】:2020-11-04 01:56:55
【问题描述】:

我向 CocktailDB API 创建一个请求并从 JSON 输出中获取鸡尾酒的类别,然后将所有鸡尾酒的类别添加到一个数组中。

我想在我的表格视图中显示数组中的元素。
但是tableview是空的,categoriesArray.count返回0。

我的代码:

class ViewController: UIViewController {
    
    struct Categories {
        let categoryName: String
    }
    
    @IBOutlet weak var tableView: UITableView!
    var categoriesArray = [String]()
    
    override func viewDidLoad() {
        super.viewDidLoad()
        getCategories()
    }
    
    func getCategories() {
        let url = URL(string: "https://www.thecocktaildb.com/api/json/v1/1/list.php?c=list")!
        
        let session = URLSession.shared
        
        let task = session.dataTask(with: url) { (data, response, error) in
            do {
                let jsonData = try JSONSerialization.jsonObject(with: data!, options: []) as? [String: Any]
                let output = self.jsonParserCategories(jsonData!)
                
                self.categoriesArray.append(contentsOf: output)
                print(self.categoriesArray) // print out an array of categories

            } catch {
                print(error)
                return
            }
        }
        task.resume()
    }
    
    private func jsonParserCategories(_ data: [String: Any]) -> [String] {
        var categArray: [String] = []
        
        let allDrinks = data["drinks"] as! [Any]
        
        allDrinks.forEach {
            categArray.append(($0 as! [String: Any])["strCategory"] as! String)
        }
        
        return categArray
    }
}

extension ViewController: UITableViewDelegate, UITableViewDataSource {
    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return 2
    }
    
    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        return UITableViewCell(style: .default, reuseIdentifier: "cell")
    }
    
    func numberOfSections(in tableView: UITableView) -> Int {
        return categoriesArray.count // return 0 
    }
    
    func tableView(_ tableView: UITableView, titleForHeaderInSection section: Int) -> String? {
        return categoriesArray[section]
    }
}

JSON 结构:

【问题讨论】:

    标签: ios json swift api uitableview


    【解决方案1】:

    收到回复后重新加载表格数据

    func getCategories() {
            let url = URL(string: "https://www.thecocktaildb.com/api/json/v1/1/list.php?c=list")!
            
            let session = URLSession.shared
            
            let task = session.dataTask(with: url) { (data, response, error) in
                do {
                    let jsonData = try JSONSerialization.jsonObject(with: data!, options: []) as? [String: Any]
                    let output = self.jsonParserCategories(jsonData!)
                    
                    self.categoriesArray.append(contentsOf: output)
                    print(self.categoriesArray) // print out an array of categories
                    DispatchQueue.main.async {
                        tableView.reloadData()
                      }
    
                } catch {
                    print(error)
                    return
                }
            }
            task.resume()
        }
    

    【讨论】:

    • 如果您遇到任何其他问题,请告诉我...祝您编码愉快,您可以为任何答案投票
    【解决方案2】:

    您必须在设置数据后调用reloadData。另外,在 getCategories 方法的开头将数组设置为空。

    func getCategories() {
        categoriesArray = [] // set array to empty
        //...
        self.categoriesArray.append(contentsOf: output)
        DispatchQueue.main.async {
            self.tableView.reloadData() // call reload once `categoriesArray` is set
        }
    

    附加组件:使用Codable 模型解码JSON 而不是JSONSerialization

    【讨论】:

    • 它有效,谢谢!这么愚蠢的错误。我将 :Decodable 添加到我的 Categories 结构并更改 JSONSerialization 以让 jsonData = try JSONDecoder().decode([Categories].self, from: data!)。请建议我现在如何使用我的 jsonParserCategories() 方法解析 jsonData,因为 jsonData 现在不会遇到 [String: Any] 类型?
    • 太棒了。修改var categoriesArray = [Categories]()。并在cellForItem 方法中使用Categories 模型。
    • 但我仍然让 output = self.jsonParserCategories(jsonData) 并且它说“无法将类型 '[ViewController.Categories]' 的值转换为预期的参数类型 '[String : Any]'”因为应该在我的 jsonParserCategories() 方法中传递另一种类型。我应该在这里改变什么?
    • 您必须将数据作为参数传递,而不是您已序列化的 jsonData。您能否将您的疑问添加为另一篇帖子并将链接添加到 cmets 中,我会看看并帮助您弄清楚您需要做什么。
    • 我需要等待一个小时才能发布另一个问题 :( 现在我有这个问题:i.stack.imgur.com/NGR7q.png
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-01-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-09-11
    相关资源
    最近更新 更多