问题描述
我正在使用CocktaildB API并遇到一些问题.
我创建了一个从特定类别获取鸡尾酒(每个鸡尾酒的名称和图像)的请求.然后,我尝试使用可解码协议解析JSON.但是它不起作用,并且显示了JSON错误.
因此,我想从以下请求中获取鸡尾酒类别," https://www.thecocktaildb.com/api/json/json/v1/1/list.php?c=list"和每个类别都有一个部分(显示)标题中的类别名称)带有本节的鸡尾酒.
我的饮料模型:
struct Drinks:Decodable { var drinks: [Drink] } struct Drink:Decodable { var strDrink: String var strDrinkThumb: String }
我的类别模型:
struct Categories: Decodable { var drinks: [Drink] } struct Category: Decodable { var strCategory: String }
我的代码:
class ViewController: UIViewController { var drinks = [Drinks]() var categories = [Categories]() override func viewDidLoad() { super.viewDidLoad() downloadJSON() } func downloadJSON() { let category = "Cocoa" // for example let url = URL(string: "https://www.thecocktaildb.com/api/json/v1/1/filter.php?c=\(category)") URLSession.shared.dataTask(with: url!) { (data, response, error) in if error == nil { do { self.drinks = try JSONDecoder().decode([Drinks].self, from: data!) print(self.drinks) } catch { print("JSON Error") } } }.resume() } } extension ViewController: UITableViewDataSource, UITableViewDelegate { func numberOfSections(in tableView: UITableView) -> Int { return drinks.count } func tableView(_ tableView: UITableView, titleForHeaderInSection section: Int) -> String? { return "" } func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { return 1 } func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { return UITableViewCell(style: .default, reuseIdentifier: "cell") } }
JSON结构:
推荐答案
您需要在此处进行一些其他更改.一个将解码更改为Drinks.self.然后重新加载tableView.并返回截面标题的字符串.这是代码:
解码:
var drinks = [Drink]() // modify the drinks property if let data == data { do { self.drinks = try JSONDecoder().decode(Drinks.self, from: data).drinks DispatchQueue.main.async { self.tableView.reloadData() } } catch { print(error) } }
和title forheaderInsection方法:
func tableView(_ tableView: UITableView, titleForHeaderInSection section: Int) -> String? { return drinks[section].strDrink }
其他推荐答案
错误很明显.而不是阵列(如您的[Drinks].self所示),您会收回字典(将其映射到您的Drinks struct):
drinks = try JSONDecoder().decode(Drinks.self, from: data!)
当然这意味着:
var drinks也变成Drinks(而不是[Drinks])
问题描述
I'm working with CocktailDB API and having some problems.
I create a request to get cocktails (each cocktail's name and image) from specific category. Then I try to parse JSON with Decodable protocol. But it doesn't work and JSON Error is displayed.
Therefore I want to get cocktails categories from the following request "https://www.thecocktaildb.com/api/json/v1/1/list.php?c=list" and have a section for each category (display category name in a header) with the cocktails from this section.
My Drink Model:
struct Drinks:Decodable { var drinks: [Drink] } struct Drink:Decodable { var strDrink: String var strDrinkThumb: String }
My Category Model:
struct Categories: Decodable { var drinks: [Drink] } struct Category: Decodable { var strCategory: String }
My code:
class ViewController: UIViewController { var drinks = [Drinks]() var categories = [Categories]() override func viewDidLoad() { super.viewDidLoad() downloadJSON() } func downloadJSON() { let category = "Cocoa" // for example let url = URL(string: "https://www.thecocktaildb.com/api/json/v1/1/filter.php?c=\(category)") URLSession.shared.dataTask(with: url!) { (data, response, error) in if error == nil { do { self.drinks = try JSONDecoder().decode([Drinks].self, from: data!) print(self.drinks) } catch { print("JSON Error") } } }.resume() } } extension ViewController: UITableViewDataSource, UITableViewDelegate { func numberOfSections(in tableView: UITableView) -> Int { return drinks.count } func tableView(_ tableView: UITableView, titleForHeaderInSection section: Int) -> String? { return "" } func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { return 1 } func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { return UITableViewCell(style: .default, reuseIdentifier: "cell") } }
JSON structure:
推荐答案
You need to make a few additional changes here. One change the decoding to Drinks.self. Then reload the tableView. And return the String for the section header. Here's the code:
Decoding:
var drinks = [Drink]() // modify the drinks property if let data == data { do { self.drinks = try JSONDecoder().decode(Drinks.self, from: data).drinks DispatchQueue.main.async { self.tableView.reloadData() } } catch { print(error) } }
And titleForHeaderInSection method:
func tableView(_ tableView: UITableView, titleForHeaderInSection section: Int) -> String? { return drinks[section].strDrink }
其他推荐答案
The error is pretty clear. Instead of an array (as your [Drinks].self implies) you get back a dictionary (that maps to your Drinks struct):
drinks = try JSONDecoder().decode(Drinks.self, from: data!)
which of course means that:
var drinks becomes Drinks as well (instead of [Drinks])