iOS Firebase асинхронный поиск данных в массив - PullRequest
0 голосов
/ 16 мая 2018

Я пытаюсь получить данные из Firebase в массив.Поскольку он работает асинхронно, результаты, которые я хочу показать в моем CollectionView, задерживаются до тех пор, пока я не переключусь назад и вперед.Я очень плохо знаком с асинхронными функциями в iOS.Пожалуйста, помогите мне завершить мой код.

    ref = Database.database().reference(withPath: "MyTest/Video")
        ref?.observeSingleEvent(of: .value, with: { snapshot in

            if !snapshot.exists() { return }

            if let result = snapshot.children.allObjects as? [DataSnapshot] {
                for child in result {
                    let autoID = child.key as String //get autoID

                    let title = snapshot.childSnapshot(forPath: "\(autoID)/Title").value
                    let url = snapshot.childSnapshot(forPath: "\(autoID)/URL").value
                    let views = snapshot.childSnapshot(forPath: "\(autoID)/Views").value

                    self.arrayAllTitle.append(title as! String)
                    self.arrayAllId.append(url as! String)
                    self.arrayAllDesc.append(views as! String)
                }
            }


        })

Ответы [ 2 ]

0 голосов
/ 16 мая 2018

Я работаю с Firebase в моем проекте прямо сейчас. Я бы предложил следующее решение: обернуть наблюдателя базы данных в отдельную функцию, которая получает блок завершения в качестве параметра.

func getValueFromDatabase(completion: ()->Void){

    ref = Database.database().reference(withPath: "MyTest/Video")
    ref?.observeSingleEvent(of: .value, with: { snapshot in

        if !snapshot.exists() { return }

        if let result = snapshot.children.allObjects as? [DataSnapshot] {
            for child in result {
                let autoID = child.key as String //get autoID

                let title = snapshot.childSnapshot(forPath: "\(autoID)/Title").value
                let url = snapshot.childSnapshot(forPath: "\(autoID)/URL").value
                let views = snapshot.childSnapshot(forPath: "\(autoID)/Views").value

                self.arrayAllTitle.append(title as! String)
                self.arrayAllId.append(url as! String)
                self.arrayAllDesc.append(views as! String)
            }

            completion()
        }
    })
}

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

getValueFromDatabase(completion:{

    self.collectionView.reloadData() //or any other action you want to fulfil

})
0 голосов
/ 16 мая 2018

Вам необходимо перезагрузить коллекцию после извлечения данных и после вызова цикла for reloadData()

for child in result {

}

self.collectionView.reloadData()

//

func getValueFromDatabase(completion: @escaping (_ status: Bool) -> Void){

    ref = Database.database().reference(withPath: "MyTest/Video")
    ref?.observeSingleEvent(of: .value, with: { snapshot in

        if !snapshot.exists() { return }

        if let result = snapshot.children.allObjects as? [DataSnapshot] {
            for child in result {
                let autoID = child.key as String //get autoID

                let title = snapshot.childSnapshot(forPath: "\(autoID)/Title").value
                let url = snapshot.childSnapshot(forPath: "\(autoID)/URL").value
                let views = snapshot.childSnapshot(forPath: "\(autoID)/Views").value

                self.arrayAllTitle.append(title as! String)
                self.arrayAllId.append(url as! String)
                self.arrayAllDesc.append(views as! String)
            }

            completion(true)
        }
        else {
            completion(false)
        }
    })
}

//

self.getValueFromDatabase { (status) in

    if status {
       // success 
    }
 }
...