Welcome to ShenZhenJia Knowledge Sharing Community for programmer and developer-Open, Learning and Share
menu search
person
Welcome To Ask or Share your Answers For Others

Categories

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:

enter image description here

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
thumb_up_alt 0 like thumb_down_alt 0 dislike
336 views
Welcome To Ask or Share your Answers For Others

1 Answer

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
}

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
thumb_up_alt 0 like thumb_down_alt 0 dislike
Welcome to ShenZhenJia Knowledge Sharing Community for programmer and developer-Open, Learning and Share
...