Получение пустого массива из функции Firestore (swift) - PullRequest
0 голосов
/ 21 апреля 2020

Привет, эта функция дает неожиданный результат для меня. Я новичок в программировании, поэтому я ценю любую помощь в понимании этого.

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

func readFromDatabase() -> [[String]]  {

let db = Firestore.firestore()
db.collection("Letters").getDocuments { (snapshot, error) in
    if error != nil {
        print(error?.localizedDescription ?? "error")
    } else {
        for document in (snapshot?.documents)! {
            // let fetchedData = document.data() //gets all data from all documenters unorganized
            let firstLetter = document.get("1") as! String
            let secondLetter = document.get("2") as! String
            let thirdLetter = document.get("3") as! String
            let fourthLetter = document.get("4") as! String
            let fifthLetter = document.get("5") as! String
            let sixthLetter = document.get("6") as! String
            let seventhLetter = document.get("7") as! String
            let eighthLetter = document.get("8") as! String
            let organizedData = [firstLetter,  secondLetter, thirdLetter, fourthLetter, fifthLetter, sixthLetter, seventhLetter, eighthLetter]

            self.databaseData = organizedData
            self.make2darray.append(self.databaseData) //makes 2darray

        } //closing fetch

    } //closing else statement

    print("printing", self.make2darray) // works ok

} //closing snapshot

print("printing outside snapshot", self.make2darray) //returns empty array
return self.make2darray //returns empty array

} //closing function

ОБНОВЛЕНИЕ: Я сделал следующие изменения в коде после чтения и проб несколько вещи. Это должно работать, насколько я понял, что я прочитал, но я все еще получаю пустой массив.

  func readFromDatabase(completion: @escaping ([[String]]) -> Void)  {

        let db = Firestore.firestore()
        let dispatchGroup = DispatchGroup()

        db.collection("Letters").getDocuments { (snapshot, error) in

            if error != nil {
                print(error?.localizedDescription ?? "error")
            } else {
                dispatchGroup.enter()
                for document in (snapshot?.documents)! {
                    // let fetchedData = document.data() //gets all data from all documenters unorganized
                    let firstLetter = document.get("1") as! String
                    let secondLetter = document.get("2") as! String
                    let thirdLetter = document.get("3") as! String
                    let fourthLetter = document.get("4") as! String
                    let fifthLetter = document.get("5") as! String
                    let sixthLetter = document.get("6") as! String
                    let seventhLetter = document.get("7") as! String
                    let eighthLetter = document.get("8") as! String
                    let organizedData = [firstLetter,  secondLetter, thirdLetter, fourthLetter, fifthLetter, sixthLetter, seventhLetter, eighthLetter]

                    self.databaseData = organizedData
                    self.make2darray.append(self.databaseData) //makes 2darray

                } //closing fetch

                 dispatchGroup.leave()

            } //closing else statement

            //print("printing", self.make2darray) // works ok

            dispatchGroup.notify(queue: .main){
            completion(self.make2darray) 
            }

        } //closing snapshot

    } //closing function

Ответы [ 2 ]

0 голосов
/ 22 апреля 2020

Хорошо, кто ищет ответ на этот вопрос в будущем. Вот как я смог решить проблему. Мне пришлось создать наблюдателя с ключом уведомления.

Ключ уведомления был создан как переменная прямо под объявлением класса следующим образом: let notificationKey = "#####". Ха sh будет уникальным ключом, таким как название вашего сайта или что-то в этом роде.

В viewDidLoad я вызвал createObserver () и сразу вызвал readFromDatabase ().

Что происходит, когда функция readFromDatabase () получает данные, наблюдатель ожидает сигнала от Центра уведомлений. Когда работа завершена, Центр уведомлений запускает созданный нами ключ, который сообщает наблюдателю, что процесс завершен. Теперь это означает, что «make2darray» имеет полные записи данных, извлеченные из базы данных, и готов к использованию. Мы также должны удалить наблюдателя сразу после этого, чтобы не вызывать никаких проблем позже.

Я уверен, что этот код груб, но он работает. Я новый программист, поэтому используйте любой способ, чтобы получить те же результаты для вас. Удачи тебе.

func createObserver(){
  //listening to hear if the database call is complete
    NotificationCenter.default.addObserver(self, selector: #selector(ViewController.readFromDatabase), name: NSNotification.Name(rawValue: notificationKey), object: nil)
}

@objc func readFromDatabase() {

let db = Firestore.firestore()
db.collection("Letters").getDocuments { (snapshot, error) in

    if error != nil {
        print(error?.localizedDescription ?? "error")
    } else {

        for document in (snapshot?.documents)! {
            // let fetchedData = document.data() //gets all data from all documenters unorganized
            let firstLetter = document.get("1") as! String
            let secondLetter = document.get("2") as! String
            let thirdLetter = document.get("3") as! String
            let fourthLetter = document.get("4") as! String
            let fifthLetter = document.get("5") as! String
            let sixthLetter = document.get("6") as! String
            let seventhLetter = document.get("7") as! String
            let eighthLetter = document.get("8") as! String
            let organizedData = [firstLetter,  secondLetter, thirdLetter, fourthLetter, fifthLetter, sixthLetter, seventhLetter, eighthLetter]

            self.databaseData = organizedData
            self.make2darray.append(self.databaseData) //makes 2darray

        } //closing fetch
    } //closing else statment

    //Notifies the observer that the process is complete
        NotificationCenter.default.post(name: NSNotification.Name(rawValue: self.notificationKey), object: nil)

   //Removing the observer
    NotificationCenter.default.removeObserver(self)

} //closing database call

//verifying all entries are present
//print("printing outside database call", self.make2darray.count)

} //closing function
0 голосов
/ 21 апреля 2020

Вы можете вызывать оператор print слишком рано, попробуйте вызвать его после запуска функции

override func viewdidload() {
super.viewDidLoad()
readFromDatabase()
print (make2darray)
}

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