简体   繁体   中英

Pass Json response from one Viewcontroller to another Viewcontroller and populate CollectionView

I'm trying to pass a Json response of an Http request from one controller to another, where in the second one I'd like to create a collection view from the recieved data.


import UIKit

class TableViewController: UITableViewController {

    let ingredientList = Ingredients().Ingredients
    public var arrayDrinks: Array<Any> = []
    let session = URLSession.shared


    override func viewDidLoad() {
        super.viewDidLoad()

        self.tableView.reloadData()
        tableView.dataSource = self
        tableView.delegate = self

    }

    override func numberOfSections(in tableView: UITableView) -> Int {
        return 1
    }

    // MARK: - number of rows
    override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return self.ingredientList.count
    }

    // MARK: - creating cell
    override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let cell = tableView.dequeueReusableCell(withIdentifier: "cellaIng", for: indexPath)

        let singoloIngrediente = self.ingredientList[indexPath.row]

        cell.textLabel?.text = singoloIngrediente
        return cell
    }


    // MARK: - get the Selected Item
    override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {

        let selectedItem: String = ingredientList[indexPath.row]
        print("The selected ingredient is: \(selectedItem)")

        // parameter for http request
        let param = String(selectedItem.replacingOccurrences(of: " ", with: "_"))

        let url = URL(string: "https://www.thecocktaildb.com/api/json/v1/1/filter.php?i=\(param)")!

        // MARK: - Http request

        let task = session.dataTask(with: url) { data, response, error in

            if error != nil || data == nil {
                print("Client error!")
                return
            }

            guard let response = response as? HTTPURLResponse, (200...299).contains(response.statusCode) else {
                print("Server error!")
                return
            }

            do {
                // data from network request
                let decoder = JSONDecoder()
                let response = try decoder.decode(ObjectDrink.self, from: data!) // ObjectDrink from Model

                self.arrayDrinks.append(response.drinks)
                let destinationVC = DrinksListCollectionViewController()
                destinationVC.remoteArray = response.drinks
                 print("print array drink \(destinationVC.remoteArray)")

            } catch { print(error) }

        }
        performSegue(withIdentifier: "InglistSegue", sender: self)
         task.resume()

//        let destinationVC = DrinksListCollectionViewController()
//        destinationVC.remoteArray = self.arrayDrinks
//        destinationVC.performSegue(withIdentifier: "InglistSegue", sender: self)

    } // END didSelectRowAt

}

When I print the response to the console, the array of the second controller is empty, so no data is passing from the first response (array) to the other controller

The view controller that you are moving to is not available yet and your line:

let destinationVC = DrinksListCollectionViewController()

Creates a new view controller which is not the one that your app transitions to. To use the view controller that will be shown, you use prepare(for segue: UIStoryboardSegue, sender: Any?) like so:

override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
    if let destinationVC = segue.destination as? DrinksListCollectionViewController {
        destinationVC.remoteArray = self.arrayDrinks
    }
}

You need to present it inside the callback of the URLSession.shared.dataTask like

DispatchQueue.main.async {
    self.arrayDrinks.append(response.drinks)
    let destinationVC = DrinksListCollectionViewController()
    destinationVC.remoteArray = response.drinks
    print("print array drink \(destinationVC.remoteArray)")
    self.present(destinationVC,animated:true,completion:nil)
}

If it's a segue then replace above with ( also inside the completion )

DispatchQueue.main.async {
  performSegue(withIdentifier: "InglistSegue", sender: response.drinks)
}

Add this method

override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
  let destinationVC = segue.destination as! DrinksListCollectionViewController 
  destinationVC.remoteArray = sender as! [Model] // model it type of drinks 
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM