Как наблюдать больше уровней из базы данных в реальном времени Firebase? - PullRequest
0 голосов
/ 18 февраля 2019

Мой код не добавляет значения из оператора while для UIViewController в массив UITableViewController.

Это функция получения, позволяющая мне видеть все дочерние значения вдругие детские.Теперь я собираюсь быть более конкретным:

Мой узел базы данных состоит из:

Автомобили -> 0, 1, 2, 3, ... -> Модель,Цена, ... -> Строка

Как видите, число детей не определено, поэтому я должен использовать этот метод управления:

while let child = snapshotChildren.nextObject() as? DataSnapshot {
            // Get code node key and save it to cars array
        }

Прежде всегоВ загрузке ViewController я получаю кодовые ключи узлов автомобилей и сохраняю их в переменную автомобилей типа NSMutableArray из TableViewController.Затем я сделаю то же самое в TableViewController, чтобы получить все indexpath.row дочерние значения.

let rootRef = Database.database().reference()
    let carconditionalRef = rootRef.child("Cars")
    carconditionalRef.observe(.value) {(snap: DataSnapshot) in
//Get all the children from snapshot you got back from Firebase
    let snapshotChildren = snap.children
//Loop over all children (code) in Firebase
        while let child = snapshotChildren.nextObject() as? DataSnapshot {
                  // Get code node key and save it to cars array
                     let carvc = Cars_Table();
                     carvc.cars.add(child.key)
             }
         }

В результате с этим кодом у меня все еще будет пустое NSMutableArray.Как я могу решить эту проблему?

Изменить 1


Я исправил этот фрагмент к этому:

import UIKit
import FirebaseDatabase

class Loading: UIViewController {


    @IBOutlet weak var loading: UIActivityIndicatorView!

    var mother: NSMutableArray = []

    override func viewDidLoad() {
        super.viewDidLoad()
        start()
    }

    func start() {

        loading.startAnimating()
        if #available(iOS 10.0, *) {
            Timer.scheduledTimer(withTimeInterval: 0.1, repeats: false) { (timer) in

                //let's dance
                self.loading.startAnimating()

                //call data from database
                let rootRef = Database.database().reference()
                let conditionalRef = rootRef.child("Cars")
                conditionalRef.observe(.value) {(snap: DataSnapshot) in
                    // Get all the children from snapshot you got back from Firebase
                    let snapshotChildren = snap.children
                    // Loop over all children (code) in Firebase
                    while let child = snapshotChildren.nextObject() as? DataSnapshot {
                        // Get code node key and save it to cars array
                        self.mother.add(child.key)
                    }

                    self.move()
                    self.loading.stopAnimating()
                    self.performSegue(withIdentifier: "loadingfinish", sender: nil)



                }
            }
        } else {
            // Fallback on earlier versions
        }

    }

    func move() {

    let vc = Cars_Table()
        vc.cars = self.mother

    }

}

Редактировать 2


Я пытался использовать рекурсивный метод, но он не работал.Поэтому я попробовал еще раз с итерационным методом на этот раз, используя оператор while.

Здесь моя новая функция, на этот раз прямо в Car_TableView.swift:

func loadData() {
    //call data from database
    let rootRef = Database.database().reference()
    let conditionalRef = rootRef.child("Cars")
    conditionalRef.observe(.value) {(snap: DataSnapshot) in
        // Get all the children from snapshot you got back from Firebase
        let snapshotChildren = snap.children
        // Loop over all children (code) in Firebase

        while let child = snapshotChildren.nextObject() as? DataSnapshot {
            // Get code node key and save it to cars array
            self.populateTable.append(child.key)
        }

        var counter = 0

        while counter > -self.populateTable.count {
            counter -= 1

            let rootRef = Database.database().reference()

                let userRef = rootRef.child("Cars").child("\(self.populateTable.count+counter)")

                userRef.observeSingleEvent(of: .value, with: { snapshot in
                    let userDict = snapshot.value as! [String: Any]

                        let model1 = userDict["Model"] as! String
                        self.model.add(model1)

                        let detail1 = userDict["Detail"] as! String
                        self.detailpage.add(detail1)

                        let year1 = userDict["Year"] as! String
                        self.year.add(year1)

                        let carPrice1 = userDict["Price"]  as! String
                        self.price.add(carPrice1)

                        let carimageURL1 = userDict["imageURL"]  as! String
                        self.imagePathString.add(carimageURL1)
                }) //end observeSingleEvent



        }

        }
  }

Когда яиди, чтобы сделать while, observeSingleEvent будет работать, но это будет повторяться n ^ 2 раза.Почему это происходит?

Редактировать 3


Поскольку проблема, кажется, изменилась с самого начала, я отредактировал, чтобы дать все соответствующие детали.Итак, проблема теперь другая и теперь две:

  1. Когда я загружаю базу данных, у меня есть n ^ 2 повторных инструкций
  2. Чтобы увидеть таблицу, заполненную данными базы данных, я долженнажмите кнопку панели вкладок, чтобы перейти к следующему ViewController, затем нажмите кнопку панели вкладок, чтобы вернуться к Car_TableView.swift

Для первой проблемы ... в общем, я понятия не имею, почему это происходит ?

Для второй проблемы я подумал использовать SVProgressHUD для перезагрузки данных, но он не работает с функцией loadData(), и если я пытаюсь использовать метод экземпляра tableView.reloadData(), он вылетает.

переменныевсе NSMutableArray с тех пор, как я должен загрузить много вещей, которые могут измениться во времени

Моя viewDidLoad() функция очень проста, как вы можете видеть:

 override func viewDidLoad() {
        super.viewDidLoad()
        loadData()
    }

Этомой источник данных табличного представления в нашем Car_TableView.swift:

override func numberOfSections(in tableView: UITableView) -> Int {
        return populateTable.count
    }

    override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {

        return populateTable.count
    }


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

        let cellIdentifier = "carTableCell"

        let cell = tableView.dequeueReusableCell(withIdentifier: cellIdentifier) as! Car_Cell


        cell.carLabel?.text = "\(self.model[indexPath.row])"
        cell.carSubtitle?.text = "Year: \(self.year[indexPath.row]) - Price: \(self.price[indexPath.row])$"


        Alamofire.request("\(self.imagePathString[indexPath.row])").response { response in
            guard let image = UIImage(data:response.data!) else {
                // Handle error
                return
            }
            let imageData = image.jpegData(compressionQuality: 1.0)
            cell.carImage.contentMode = .scaleAspectFit
            cell.carImage.image = UIImage(data : imageData!)
        }

        return cell
    }



    override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
        if segue.identifier == "ShowcarDetails" {

            let myIndexPath = self.tableView.indexPathForSelectedRow!

            //save detail page url in UserDefault
            let SVDetail = self.detailpage[myIndexPath.row]
            let SVDetaildefaults = UserDefaults.standard
            SVDetaildefaults.set(SVDetail, forKey: "sv_detail")
            SVDetaildefaults.synchronize()

            _ = segue.destination
                as! Car_Detail
        }
    }

    //SET CELLS SIZE
    override func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
        switch indexPath.row {
        case 0,1,2,3,4:
            return 100
        default:
            return 100
        }
    }

Я также повторно опубликовал функцию loadData(), потому что я упростил операцию только в операторе while:

func loadData() {
        //call data from database
        let rootRef = Database.database().reference()
        let conditionalRef = rootRef.child("Cars")
        conditionalRef.observe(.value) {(snap: DataSnapshot) in
            // Get all the children from snapshot you got back from Firebase
            let snapshotChildren = snap.children
            // Loop over all children (code) in Firebase
            while let child = snapshotChildren.nextObject() as? DataSnapshot {
                // Get code node key and save it to cars array
                self. populateTable.append(child.key)

                    let userRef = rootRef.child("Cars").child("\(child.key)")

                    userRef.observeSingleEvent(of: .value, with: { snapshot in
                        let userDict = snapshot.value as! [String: Any]

                            let address1 = userDict["Address"] as! String
                            self.address.add(address1)

                            let detail1 = userDict["Detail"] as! String
                            self.detailpage.add(detail1)

                            let carnumberOfRooms1 = userDict["numberOfRooms"] as! String
                            self.numberOfRooms.add(carnumberOfRooms1)

                            let carPrice1 = userDict["Price"]  as! String
                            self.price.add(carPrice1)

                            let carimageURL1 = userDict["imageURL"]  as! String
                            self.imagePathString.add(carimageURL1)
                    }) //end observeSingleEvent

            } //end while



            } //end snap

      }//end func
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...