0

I am wanting the search bar to return the title for each object in the Array. I believe the problem is in my for loop but I am not completed sure. Hopefully, you guys are able to tell me what I am doing wrong.

I am searching through an API. This is the array I am attempting to search through

struct ProductResponse: Decodable {
    let results: [SearchResults]
}

struct SearchResults: Decodable {
    let title: String
    let id:Int
}

I created a for loop to run through each object in the array and get the title and id.

func fetchProduct(productName: String) {
    let urlString = "\(searchURL)&query=\(productName)&number=25"
    performRequest(urlString: urlString)
}
func performRequest(urlString: String) {
    
    // Create a URL
    
    if let url = URL(string: urlString) {
        
        //Create a URLSession
        
        let session = URLSession(configuration: .default)
        // Give the session a task
        
        let task = session.dataTask(with: url) { (data, response, error) in
            if error != nil {
                print(error!)
                return
            }
            if let safeData = data {
                self.parseJSON(productTitle: safeData)
            }
            
        }
        
        // Start the task
        task.resume()
        
        
    }
    
}

func parseJSON(productTitle: Data) {
    let decoder = JSONDecoder()
    do {
    let decodedData = try decoder.decode(ProductResponse.self, from: productTitle)
        
        print(decodedData.results)
    } catch {
        print(error)
    }
}

}

I created this function to reload the data in my tableview. When I search for the product results in the Search Bar, my tableview doesn't return anything. The goal is to have my tableview return each result in a tableview cell

var listOfProducts = [SearchResults]() {
    didSet {
        DispatchQueue.main.async {
            self.tableView.reloadData()
            self.navigationItem.title = "\(self.listOfProducts.count) Products found"
        }
    }
}

override func viewDidLoad() {
    super.viewDidLoad()
    productSearch.delegate = self

}

func downloadJSON() {
    guard let downloadURL = url else { fatalError("Failed to get URL")}
    
    URLSession.shared.dataTask(with: downloadURL) { (data, Response, error) in
        print("downloaded")
    }.resume()
}
// MARK: - Table view data source

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

override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
    // #warning Incomplete implementation, return the number of rows
    return listOfProducts.count
}
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
    let cell = tableView.dequeueReusableCell(withIdentifier: "Cell", for: indexPath)
    
    let product = listOfProducts[indexPath.row].title
    
    cell.textLabel?.text = product

    
    return cell
}


}

extension ProductsTableViewController: UISearchBarDelegate {
    func searchBarSearchButtonClicked(_ searchBar: UISearchBar) {
        if let searchBarText = searchBar.text {
            searchRequest.fetchProduct(productName: searchBarText)
        }
    }
}

This is the result enter image description here

Andrew
  • 27
  • 4
  • Hey Andrew, Under the parseJSON method you applied a loop to get the title of each object, but could you confirm under the same function variable "decodedData.results" have value or not? If yes that variable contains a value then why should you have used for loop, because I saw you have used table view you can pass that variable and use each object title using=> result[indexpath.row]?.title on your cell for row at. – Ashutosh Mishra Jul 19 '20 at 04:36
  • Thanks for that @AshutoshkumarMishra . So I printed out the results of the decodedData.results and got back the title and id of each product. My problem now my table view cells don't show the title. All I get is blank cells. – Andrew Jul 19 '20 at 18:13
  • So when you printed out the results of the decodedData.results and got the result in the form of an array then assign that array to your "listOfProducts" variable and reload the table view. – Ashutosh Mishra Jul 19 '20 at 19:21
  • Hey @AshutoshkumarMishra, For some reason when ai print out listOfProducts, it doesn't return anything. Even though I am setting the variable to the array of [SearchResults]. I feel like it's something simple that I am missing. – Andrew Jul 20 '20 at 22:54
  • Hello Andrew, If you have data in "decodedData.results" then definitely It assigns to "listOfProducts" then after it reloads the table. – Ashutosh Mishra Jul 21 '20 at 04:41

1 Answers1

0

If everything goes well and You got the data under "decodedData.results" of "parseJSON" method, And I saw "decodedData.results" and "listOfProducts" both variables are the same type of SearchResults. So you can just add the one line of under "parseJSON" method as follows:-

 func parseJSON(productTitle: Data) {
  let decoder = JSONDecoder()
  do {
  let decodedData = try decoder.decode(ProductResponse.self, from: productTitle)
    
     print(decodedData.results)// it have some array data of type SearchResults
     self.listOfProducts = decodedData.results
     self.tableView.reloadData()

   } catch {
    print(error)
  }
}
Ashutosh Mishra
  • 1,679
  • 1
  • 13
  • 16