Hùng Vũ
Hùng Vũ

Reputation: 1

Get data to another func from observer of firebase

I have problem with use data from firebase after get them. I written function getData() in model, use delegate to call them on UITableViewController and set data to TableView. But when I create new array to get data from func getData(), this array is nil.

This is my model:

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)
        })
    }
}

And there is class 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
    }```

Upvotes: 0

Views: 82

Answers (2)

axel
axel

Reputation: 422

One solution would be to change-remove your protocol implementation and use a completion block in your getListBook func. Delete myDelegate reference from your ListStoryTableView and do the following change:

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)
    })
  }

and then in your viewDidLoad or any other function you use the following to fetch your data:

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

I hope that helps you.

Upvotes: 1

Shahzaib Qureshi
Shahzaib Qureshi

Reputation: 920

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

print listBook in this function and you will have the data..

Upvotes: 0

Related Questions