class ViewController: UIViewController,UITableViewDelegate,UITableViewDataSource,UISearchBarDelegate,UISearchDisplayDelegate{
@IBOutlet weak var recipeTable: UITableView!
// search functionality
@IBOutlet weak var searchbarValue: UISearchBar!
var isSearching = false
func searchBarTextDidBeginEditing(_ searchBar: UISearchBar) {
isSearching = true
}
func searchBar(_ searchBar: UISearchBar, textDidChange searchText: String){
filteredRecipes.removeAll()
if let searchText = searchBar.text, !searchText.isEmpty {
self.filteredRecipes = self.recipes.filter { recipe in
guard let ingredients = recipe.ingredients else { return false }
return ingredients.contains { $0.range(of: searchText, options: .caseInsensitive) != nil }
}
} else {
self.filteredRecipes = self.recipes
}
recipeTable.reloadData();
recipeTable.reloadInputViews();
searchBar.resignFirstResponder()
}
//end search parameters
// tableview functionionalitys
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
if isSearching == true{
return filteredRecipes.count
}else{
return recipes.count
}
}
// tableview functionalities
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath) as! RecipeTableViewCell
if isSearching == true {
cell.recipeLabel.text = self.filteredRecipes[indexPath.row].title
}else{
cell.recipeLabel.text = recipes[indexPath.row].title
}
return cell
}
// structs for json
struct Root : Decodable {
let count : Int
let recipes : [Recipe]
}
struct Recipe : Decodable { // It's highly recommended to declare Recipe in singular form
let recipeId : String
let imageUrl, sourceUrl, f2fUrl : URL
let title : String
let publisher : String
let socialRank : Double
let page : Int?
let ingredients : [String]?
}
//recipes is array of Recipes
var recipes = [Recipe]() // array of recipes
//unfiltered recipes to put into search
var filteredRecipes = [Recipe]()
fileprivate func getRecipes() {
let jsonURL = "https://www.food2fork.com/api/search?key=5eab2ddd88c29929467a3bb69a182070"
//.data(using: .utf8)!
guard let url = URL(string: jsonURL) else{return}
URLSession.shared.dataTask(with: url) {(data, response , err) in
if let response = response as? HTTPURLResponse, response.statusCode != 200 {
print(response.statusCode)
return
}
DispatchQueue.main.async {
if let err = err{
print("failed to get data from URL",err)
return
}
guard let data = data else{return}
//print(String(data: data, encoding: .utf8))
do {
let decoder = JSONDecoder()
decoder.keyDecodingStrategy = .convertFromSnakeCase
let result = try decoder.decode(Root.self, from: data)
self.recipes = result.recipes
//print(result.recipes)
self.recipeTable.reloadData()
}catch let jsonERR {
print("Failed to decode",jsonERR)
}
}
}.resume()
}
override func viewDidLoad() {
super.viewDidLoad()
//search functionalities
//call json object
getRecipes()
}
}
在我的Tableview CellforRowAt中,我在else语句中遇到了线程错误,我不确定它从哪里来。昨晚所有功能都在该函数中运行,但是今天早晨运行时,它将不会超出此错误。我允许任意负荷等。在失眠中解析JSON时,我没有收到错误403。
cell.recipeLabel.text = recipes[indexPath.row].title
Thread 1: Fatal error: Unexpectedly found nil while unwrapping an Optional value