Невозможно установить значение Textfield как результата поиска Firebase - Swift - PullRequest
0 голосов
/ 18 февраля 2019

У меня есть функция поиска в моем приложении для поиска в моей базе данных Firebase на основе введенного названия паба.Это работает правильно и возвращает правильную запись в моей консоли.Однако я пытаюсь отобразить относящуюся к этому поисковому запросу информацию в виде значений в моих текстовых полях.

var drinkReference: DatabaseReference!
let databaseRef = Database.database().reference()

@IBOutlet weak var pintImage: UIImageView!
@IBOutlet weak var pubName: UITextField!
@IBOutlet weak var pubLocation: UITextField!
@IBOutlet weak var price: UITextField!
@IBOutlet weak var rating: UITextField!
@IBOutlet weak var comment: UITextField!

@IBOutlet weak var searchText: UITextField!



override func viewDidLoad() {
    super.viewDidLoad()

    let tap: UITapGestureRecognizer = UITapGestureRecognizer(target: self, action: #selector(AddDrinkVC .dismissKeyboard))

    view.addGestureRecognizer(tap)

    drinkReference = Database.database().reference().child("Drinks");

    NotificationCenter.default.addObserver(self, selector: #selector(SearchVC.keyboardWillShow), name: NSNotification.Name.UIKeyboardWillShow, object: nil)
    NotificationCenter.default.addObserver(self, selector: #selector(SearchVC.keyboardWillHide), name: NSNotification.Name.UIKeyboardWillHide, object: nil)
}




@IBAction func searchIsClicked(_ sender: Any) {
    searchT()
}



@IBAction func homeClicked(_ sender: Any) {
    homeClicked()
}


func searchT() {
    // You must cast pub variable as String.
    guard let pub: String = searchText.text else { return }



    let databaseRef = Database.database().reference().child("Drinks")

    let query = databaseRef.queryOrdered(byChild: "pub").queryStarting(atValue: pub).queryEnding(atValue: "\(String(describing: pub))\\uf8ff")

    query.observeSingleEvent(of: .value) { (snapshot) in
        guard snapshot.exists() != false else {

            let alert = UIAlertController(title: "", message: "This pub hasn't been visited yet. We'll get there.", preferredStyle: UIAlertControllerStyle.alert)
            let search = UIAlertAction(title: "Want to add the drink yourself?", style: .default) { [weak self] _ in
                self?.uploadClicked()
            }
            alert.addAction(search)
            alert.addAction(UIAlertAction(title: "Close & Search again", style: UIAlertActionStyle.default, handler: nil))
            self.present(alert, animated: true, completion: nil)


            return }
        print(snapshot.value as Any)
        DispatchQueue.main.async {

            guard let dict = snapshot.value as? [String:Any] else {
                print(snapshot)
                return
            }



            let returnedPubName = dict["pub"] as? String
            let returnedPubLocation = dict["location"] as? String
            let returnedPintPrice = dict["price"] as? String
            let returnedPintRating = dict["rating"] as? String
            let returnedComment = dict["comment"] as? String



            self.pubName.text?.append(returnedPubName!)
            self.pubLocation.text?.append(returnedPubLocation!)
            self.price.text?.append(returnedPintPrice!)
            self.rating.text?.append(returnedPintRating!)
            self.comment.text?.append(returnedComment!)

        }
    }
}

Когда я пытаюсь присвоить значение pubName текстовому полю с тем же именем, оно получает nil.Это из-за моего кода «сторожи пусть диктует ...»?

Кто-нибудь знает, как и где я здесь ошибаюсь?

Спасибо, E enter image description here

Ответы [ 2 ]

0 голосов
/ 18 февраля 2019

Таким образом, методом проб и ошибок и с помощью нескольких людей это рабочий код, в качестве примечания я не уверен, является ли это наиболее эффективным способом или чем-то еще, но он работает так хорошо.

func searchT() {
    // You must cast pub variable as String.
        guard let pub: String = searchText.text else { return }

        let databaseRef = Database.database().reference().child("Drinks")

        let query = databaseRef.queryOrdered(byChild: "pub").queryStarting(atValue: pub).queryEnding(atValue: "\(String(describing: pub))\\uf8ff")

        query.observeSingleEvent(of: .value) { (snapshot) in
            guard snapshot.exists() != false else {

                let alert = UIAlertController(title: "", message: "This pub hasn't been visited yet. We'll get there.", preferredStyle: UIAlertControllerStyle.alert)
                let search = UIAlertAction(title: "Want to add the drink yourself?", style: .default) { [weak self] _ in
                    self?.uploadClicked()
                }
                alert.addAction(search)
                alert.addAction(UIAlertAction(title: "Close & Search again", style: UIAlertActionStyle.default, handler: nil))
                self.present(alert, animated: true, completion: nil)

                return }
            print(snapshot.value as Any)
            DispatchQueue.main.async {


                // DATA WAS FOUND
                for user_child in (snapshot.children) {

                    let user_snap = user_child as! DataSnapshot
                    let dict = user_snap.value as! [String: String?]

                    // DEFINE VARIABLES FOR LABELS
                    let returnedPubName = dict["pub"] as? String
                    let returnedPubLocation = dict["location"] as? String
                    let returnedPintPrice = dict["price"] as? String
                    let returnedPintRating = dict["rating"] as? String
                    let returnedComment = dict["comment"] as? String



                    self.pubName.text?.append(returnedPubName!)
                    self.pubLocation.text?.append(returnedPubLocation!)
                    self.price.text?.append(returnedPintPrice!)
                    self.rating.text?.append(returnedPintRating!)
                    self.comment.text?.append(returnedComment!)

            }
        }
    }
}

Обратите особое внимание на код, следующий за комментарием // НАЙДЕНЫ ДАННЫЕ, которые получают доступ к значениям записей дочерних данных.

0 голосов
/ 18 февраля 2019

Создайте структуру, подобную этой: -

struct Names {

var pub: String = ""
var location: String = ""
var price: String = ""
var rating: String = ""
var comment: String = ""


init(data: [String:Any]) {

    if let obj = data["pub"] as? String {
        self.pub = obj
    }
    if let obj = data["location"] as? String {
        self.location = obj
    }
    if let obj = data["price"] as? String {
        self.price = obj
    }
    if let obj = data["rating"] as? String {
        self.rating = obj
    }
    if let obj = data["comment"] as? String {
        self.comment = obj
    }
}
}

И в вашем классе контроллера создайте переменную

var names: [Names] = [Names]()

Затем в вашем методе searchT сделайте это

guard let dict = snapshot.value as? [String:Any] else {

            return
        }
        self.names.append(Names(data: dict))
            print(self.names)

А затем используйте

 self.pubName.text = names.first?.pub

И если это не работает, попробуйте после

 DispatchQueue.main.async {

        guard let dict = snapshot.value as? [String:Any] else {

            return
        }
        self.names.append(Names(data: dict))
            print(self.names)


    }
     self.pubName.text = names.first?.pub
...