Получение данных в другую функцию от наблюдателя firebase

#ios #swift

#iOS #swift

Вопрос:

У меня проблема с использованием данных из firebase после их получения. Я написал функцию getData() в модели, использую делегат для их вызова UITableViewController и установки данных TableView . Но когда я создаю новый массив для получения данных из функции getData() , этот массив равен нулю.

Это моя модель:

 import Foundation
import Firebase

protocol myDelegate: class {
    func didFetchData(datas: [Book])
}
class Book {
    var Id: String?
    var Author: String?
    var ChapterCount: Int?
    var CoverPhoto: String?
    var Genre: String?
    var Image: String?
    var Intro: String?
    var Like: Int?
    var Name: String?
    var Status: String?
    var UpdateDay: String?
    var UploadDay: String?
    var View: Int?

    var ref: DatabaseReference!
    weak var delegate: myDelegate?

    init()
    {

    }

    init(Id: String,Author: String,Image: String,Name: String,Status: String,UpdateDay: String,View: Int)
    {
        self.Id = Id
        self.Author = Author
        self.Image = Image
        self.Name = Name
        self.Status = Status
        self.UpdateDay = UpdateDay
        self.View = View
    }

    func getListBook() {
        ref = Database.database().reference()
        ref.child("Book").observe(.value, with: { snapshot in
            var newNames: [Book] = []
            let value = snapshot.value as? NSDictionary

            for nBook in value! {
                let val = nBook.value as? NSDictionary
                self.Name = val?["Name"] as? String ?? ""

                self.Author = val?["Author"] as? String ?? ""

                self.View = val?["View"] as? Int ?? 0

                self.Status = val?["Status"] as? String ?? ""

                self.Id = val?["Id"] as? String ?? ""

                self.Image = val?["Image"] as? String ?? ""

                self.UpdateDay = val?["UpdateDay"] as? String ?? ""

                newNames.append(Book(Id: self.Id!, Author: self.Author!, Image: self.Image!, Name: self.Name!, Status: self.Status!, UpdateDay: self.UpdateDay!, View: self.View!))
            }

            self.delegate?.didFetchData(datas: newNames)
        })
    }
}
  

И есть класс UITableViewController :

 import Firebase

class ListStoryTableView: UITableViewController, myDelegate {
    var ref: DatabaseReference!

    var book = Book()

    var listBook: [Book] = []

    func didFetchData(datas: [Book]) {
        listBook = datas
    }

    override func viewDidLoad() {
        super.viewDidLoad()

        let nib = UINib.init(nibName: "ListStoryTableViewCell", bundle: nil)
        self.tableView.register(nib, forCellReuseIdentifier: "ListStoryTableViewCell")

        book.delegate = self
        book.getListBook()

        print("(listBook)") //this is return 0
    }```
  

Комментарии:

1. вы пробовали печатать print(listBook) в didFetchData func?

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

3. если вы получаете данные didFetchData , возможно, вы печатаете свои данные перед вызовом метода делегирования. вот почему вы получаете ноль в listBook

4. После того, как вы назначите значение datas listBook в своей didFetchData функции, вам также необходимо перезагрузить свой tableView . Добавить tableView.reloadData() .

5. Итак, что мне нужно, чтобы это исправить?

Ответ №1:

Одним из решений было бы изменить — удалить вашу protocol реализацию и использовать блок завершения в вашей getListBook функции. Удалите myDelegate ссылку из вашего ListStoryTableView и выполните следующие изменения:

 func getListBook(completion: @escaping (_ books: [Book]) -> Void) {
      ref = Database.database().reference()
      ref.child("Book").observe(.value, with: { snapshot in
      var newNames: [Book] = []
      let value = snapshot.value as? NSDictionary

      for nBook in value! {
        let val = nBook.value as? NSDictionary
        self.Name = val?["Name"] as? String ?? ""

        self.Author = val?["Author"] as? String ?? ""

        self.View = val?["View"] as? Int ?? 0

        self.Status = val?["Status"] as? String ?? ""

        self.Id = val?["Id"] as? String ?? ""

        self.Image = val?["Image"] as? String ?? ""

        self.UpdateDay = val?["UpdateDay"] as? String ?? ""

        newNames.append(Book(Id: self.Id!, Author: self.Author!, Image: self.Image!, Name: self.Name!, Status: self.Status!, UpdateDay: self.UpdateDay!, View: self.View!))
      }

      completion(newNames)
    })
  }
  

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

 book.getListBook { books in
  listBook = books
  tableView.reloadData()
}
  

Надеюсь, это вам поможет.

Комментарии:

1. Ваше решение помогает мне получать данные везде. Но с помощью функции: « переопределить функцию TableView(_ TableView: UITableView, раздел numberOfRowsInSection: Int) -> Int { вернуть listBook.count } « listBook.count вернет 0

2. Каков результат print((books.count)) in book.getListBook func? Вы установили delegate и dataSource из tableView ?

Ответ №2:

 func didFetchData(datas: [Book]) {
    listBook = datas
    print("(listBook)")
}
  

распечатайте listBook в этой функции, и у вас будут данные..