如何在tableView中显示JSON数据

时间:2019-12-03 19:34:47

标签: json uitableview swift5 xcode11.2

我一直在使用食谱应用程序,您可以在其中使用勺型API搜索食谱。我已成功将JSON数据存储在数组中,但是现在我不知道当用户搜索某些内容时如何将数据获取到tableview中?到目前为止,这是我的代码。

我如何获取JSON文件并读取数据:

Class APIRequest() {

static let instance = APIRequest()

var query:String = ""
var url: String = ""
var testString: String = ""

func setQuery(_ query: String) -> Void {
    self.query = query
}

func getReturn(completed: @escaping (Result<Response, Error>) -> Void) {
    // TODO MAJOR!
    // Expressions are not allowed at top level will occur otherwise
    //

    let headers = [
        "x-rapidapi-host": "spoonacular-recipe-food-nutrition-v1.p.rapidapi.com",
        "x-rapidapi-key": "e44daac5e0mshc682df24497a89fp1c4513jsn7067934f0b9b"
    ]

    var request = URLRequest(url: URL(string: "https://spoonacular-recipe-food-nutrition-v1.p.rapidapi.com/recipes/search?number=2&query=\(query)")!,
                             cachePolicy: .useProtocolCachePolicy,
                             timeoutInterval: 10.0)
    request.httpMethod = "GET"
    request.allHTTPHeaderFields = headers

    let session = URLSession.shared
    let dataTask = session.dataTask(with: request) { (data, response, error) -> Void in
        if let error = error { completed(.failure(error));  return }
        do {
            let result = try JSONDecoder().decode(Response.self, from: data!)
            completed(.success(result))

        } catch {
            completed(.failure(error))
        }
    }
    dataTask.resume()
}

我的食谱课:

class Recipe: Codable {
let id: Int
let image: String
let title: String
let readyInMinutes: Int

init(id: Int, image: String = "Default", title: String = "Title", readyInMinutes: Int) {
    self.id = id
    self.image = image
    self.title = title
    self.readyInMinutes = readyInMinutes
}
}

recipeHandler:

class RecipeHandler {

static let instance = RecipeHandler()

var allRecipeResults: [Recipe] = []
}

然后我不确定该响应结构:

struct Response: Codable {
   struct Result: Codable {
       let id: Int
       let title: String
       let image: String
       let readyInMinutes: Int
   }
   let results: [Result]
   }

还有我的RecipeViewController:

class RecipeViewController: UITableViewController {

@IBOutlet var recipeTable: UITableView!

override func viewDidLoad() {
    super.viewDidLoad()

    recipeTable.delegate = self
    recipeTable.dataSource = self


}


}


//MARK: - Add cell
extension RecipeViewController {

override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int{
    return RecipeHandler.instance.allRecipeResults.count
    }

override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
    if let cell = tableView.dequeueReusableCell(withIdentifier: "RecipeCell") as? RecipeTableViewCell{
        let recipeItem = RecipeHandler.instance.allRecipeResults[indexPath.row]
        cell.recipeImage.image = UIImage(named: recipeItem.image)
        cell.recipeTitle.text = recipeItem.title
        cell.recipeTime.text = "\(recipeItem.readyInMinutes)"
        return cell
    }
    return UITableViewCell()
    }
    }

//MARK: - SearchBarSearchButtinClicked
extension RecipeViewController: UISearchBarDelegate{
func searchBarSearchButtonClicked(_ searchBar: UISearchBar) {
    guard let searchBarText = searchBar.text else {return}
    let request = APIRequest.instance
    request.query = searchBarText
    request.getReturn { result in
        switch result {
            case .success(let result):
                print(result.results)
                //Don't know what to do here?

            case .failure(let error):
                print(error)
        }
    }

}
}

1 个答案:

答案 0 :(得分:0)

您似乎有一个正确的主意...您正在将RecipeHandler单例用作简单数据模型,并试图从tableView:cellForRowAtIndexPath:中的那个模型中获取数据。您永远不会将任何数据放入模型中,因此没有任何东西可以得到。

        case .success(let result):
            print(result.results)
            //Don't know what to do here?

发出请求后,您的.success处理函数会被调用吗?结果会打印出来吗?如果否,那么您需要在响应处理和解码中查找问题。否则,将Result转换为配方并将其添加到模型中。