1
votes

I want to implement a functionality which is a reverse lookup. How can I query data from realm by 2 different UITextField.

There is a realm class called Items which have properties called ingredient1 to ingredient 6. I want to filter what user typed on textField base on ingredientName1 to ingredient 6. If the value user typed matched any of these properties, the variable items should be filtered.

my code:

let realm = try! Realm()
var items : Results<Items>?

@IBOutlet weak var ingredient1: UITextField!
@IBOutlet weak var ingredient2: UITextField!
@IBOutlet weak var tableView: UITableView!

When user finished typing and tapped a button. I want TableView to be refreshed and the result(recipe in this case) will be listed on it.

@IBAction func searchButton(_ sender: UIButton) {

    tableView.reloadData()
}

func textFieldDidEndEditing(_ textField: UITextField) {

    if (ingredient1.text != "" && ingredient2.text == "") {
        items = items?.filter("ingredientName1 || ingredientName2 || ingredientName3 || ingredientName4 || ingredientName5 || ingredientName6 CONTAINS[cd] %@", ingredient1)
        print(ingredient1.text!)


    } else if (ingredient1.text == "" && ingredient2.text != "") {
        print("Enter Ingredient on Ingredient1 first")

    } else if (ingredient1.text != "" && ingredient2.text != "") {
        items = items?.filter("ingredientName1 CONTAINS[cd] %@ || ingredientName2 CONTAINS[cd] %@ || ingredientName3 CONTAINS[cd] %@ || ingredientName4 CONTAINS[cd] %@ || ingredientName5 CONTAINS[cd] %@ || ingredientName6 CONTAINS[cd] %@", ingredient1.text!, ingredient2.text!)
        print("\(ingredient1.text!) \(ingredient2.text!)")
    }


}
func textFieldShouldReturn(_ textField: UITextField) -> Bool {

    textField.resignFirstResponder()
    return true
}


func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
    return items?.count ?? 1
}

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {

    let cell = tableView.dequeueReusableCell(withIdentifier: "searchedItemCell", for: indexPath)

    cell.textLabel?.text = items?[indexPath.row].itemName ?? "No items Found"

    return cell

}

This code don't throw any errors, but I get nil on items which is suppose to have any value when textFieldDidEndEditing is triggered. Then tableView stays blank.

1
where did you initialize items? calling .filter on nil will give you nothing. - Kamran
Try initializing items list first and verify this list has all the ingredients before filtering the result for intputText. - Kamran
you need fill items array - a.masri
I didn't initialize items. I fixed it but right after filtered item is substituted, I got SIGABRT error and app is crashed. - Kabalry
@IvanSmetanin If it is much easier to solve this problem, I can put git link of this project. - Kabalry

1 Answers

0
votes

First of all you need to fill items array something like this:

items = realm.objects(Items.self)

Call this in viewDidLoad. After that change your filtering strings like this:

let ingredient1Text = ingredient1.text ?? ""
items = items?.filter("ingredientName1 CONTAINS %@ ||
 ingredientName2 CONTAINS %@ || ingredientName3 CONTAINS %@ ||
 ingredientName4 CONTAINS %@ || ingredientName5 CONTAINS %@ ||
 ingredientName6 CONTAINS %@", ingredient1Text, ingredient1Text,
 ingredient1Text, ingredient1Text, ingredient1Text, ingredient1Text)

You must pass as many parameters as %@ values you have in filtering string.

For example if you want to filter by two strings you can write something like this:

let ingredient1Text = ingredient1.text ?? ""
let ingredient2Text = ingredient2.text ?? ""
cocktails = cocktails?
        .filter("ingredientName1 CONTAINS %@ || ingredientName2 CONTAINS %@ || ingredientName3 CONTAINS %@ || ingredientName4 CONTAINS %@ || ingredientName5 CONTAINS %@ || ingredientName6 CONTAINS %@ || ingredientName1 CONTAINS %@ || ingredientName2 CONTAINS %@ || ingredientName3 CONTAINS %@ || ingredientName4 CONTAINS %@ || ingredientName5 CONTAINS %@ || ingredientName6 CONTAINS %@",
            ingredient1Text, ingredient1Text, ingredient1Text, ingredient1Text, ingredient1Text, ingredient1Text, ingredient1Text,
            ingredient2Text, ingredient2Text, ingredient2Text, ingredient2Text, ingredient2Text, ingredient2Text, ingredient2Text)