-1

When I call self.tableview.reloadData() it isn't working. This code is only one time working . I searched a lot but could not find the solution.

import UIKit
import FirebaseStorage
import FirebaseDatabase
import FirebaseAuth
import FirebaseCore
import SDWebImage

class bags : UIViewController, UITableViewDelegate, UITableViewDataSource {

    @IBOutlet weak var tableView: UITableView!

    var postCommentArray = [String]()
    var useremailArray = [String]()
    var postImageURLArray = [String]()


    override func viewDidLoad() {
        super.viewDidLoad()

        getDataFromServer()

    }

    func getDataFromServer() {
        Database.database().reference().child("users").observe(DataEventType.childAdded) { (snapshot) in

            let values = snapshot.value! as! NSDictionary

            let post = values["post"] as! NSDictionary

            let postIDs = post.allKeys

            for id in postIDs {

                let singlePost = post[id] as! NSDictionary

                self.useremailArray.append(singlePost["postedby"] as! String)
                self.postCommentArray.append(singlePost["posttext"] as! String)
                self.postImageURLArray.append(singlePost["image"] as! String)

            }

                self.tableView.reloadData()

        }

    }

    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return useremailArray.count
    }

    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let cell = tableView.dequeueReusableCell(withIdentifier: "Cell", for: indexPath) as! TableView

        cell.postImage.sd_setImage(with: URL(string: self.postImageURLArray[indexPath.row]))
        cell.tarhanaIlk.text = postCommentArray[indexPath.row]
        return cell
    }

}

**Here is the tableview cell code.3 days before is working but now not working. If necessary podfile i can share. Also i tried DispatchQueue.main.async { self.tableView.reloadData() } **enter code here

import UIKit

class TableView: UITableViewCell {

    @IBOutlet weak var tarhanasonLabel: UILabel!
    @IBOutlet weak var postImage: UIImageView!
    @IBOutlet weak var tarhanaIlk: UITextView!


    override func awakeFromNib() {
        super.awakeFromNib()
        // Initialization code
    }

    override func setSelected(_ selected: Bool, animated: Bool) {
        super.setSelected(selected, animated: animated)

        // Configure the view for the selected state
    }

}

This part is the adding the data to my firebase storage

import Foundation import UIKit import FirebaseStorage import FirebaseDatabase import FirebaseAuth import FirebaseCore

class File : UIViewController {

var baslangicDegeri = 0
var iskembeadet = 0
var mercimekadet = 0
var ezogelinadet = 0
var domatesadet = 0
var sehriyeadet = 0
var etliturluadet = 0
var hamburgeradet = 0
var kanatadet = 0
var pizzaadet = 0
var etsoteadet = 0
var alabalikadet = 0
var uuid = NSUUID().uuidString



@IBOutlet weak var tarhanaadetlabel: UILabel!
@IBOutlet weak var iskembeadetlabel: UILabel!
@IBOutlet weak var mercimekadetlabel: UILabel!
@IBOutlet weak var ezogelinadetlabel: UILabel!
@IBOutlet weak var domatesadetlabel: UILabel!
@IBOutlet weak var sehriyeadetlabel: UILabel!



@IBOutlet weak var etliturluadetlabel: UILabel!
@IBOutlet weak var hamburgeradetlabel: UILabel!
@IBOutlet weak var kanatadetlabel: UILabel!
@IBOutlet weak var pizzaadetlabel: UILabel!
@IBOutlet weak var etsoteadetlabel: UILabel!
@IBOutlet weak var alabalikadetlabel: UILabel!



@IBOutlet weak var postImage: UIImageView!
@IBOutlet weak var postImageiskembe: UIImageView!
@IBOutlet weak var postImagemercimek: UIImageView!
@IBOutlet weak var postImageezogelin: UIImageView!
@IBOutlet weak var postImagedomates: UIImageView!
@IBOutlet weak var postImagesehriye: UIImageView!



@IBOutlet weak var postImageetliturlu: UIImageView!
@IBOutlet weak var postImagehamburger: UIImageView!
@IBOutlet weak var postImagekanat: UIImageView!
@IBOutlet weak var postImagepizza: UIImageView!
@IBOutlet weak var postImageetsote: UIImageView!
@IBOutlet weak var postImagealabalik: UIImageView!







override func viewDidLoad() {

    super.viewDidLoad()
}



@IBAction func tarhanaEkle(_ sender: Any) {


        let mediaFolder = Storage.storage().reference().child("media")

        if let data = UIImageJPEGRepresentation(postImage.image!, 0.5) {

            mediaFolder.child("\(uuid).jpg").putData(data, metadata: nil, completion: { (metadata, error) in
                if error != nil {
                    let alert = UIAlertController(title: "Error", message: error?.localizedDescription, preferredStyle: UIAlertControllerStyle.alert)
                    let okButton = UIAlertAction(title: "OK", style: UIAlertActionStyle.cancel, handler: nil)
                    alert.addAction(okButton)
                    self.present(alert, animated: true, completion: nil)
                } else {

                    let imageURL = metadata?.downloadURL()?.absoluteString

                    let post = ["image" : imageURL!, "postedby" : Auth.auth().currentUser!.email!, "uuid" : self.uuid, "posttext" : self.tarhanaadetlabel.text as Any] as [String : Any]
                    Database.database().reference().child("users").child((Auth.auth().currentUser?.uid)!).child("post").childByAutoId().setValue(post)

                    self.postImage.image = UIImage(named: "select.png")
                    self.tarhanaadetlabel.text = ""
                    self.tabBarController?.selectedIndex = 0

                }



            })
        }



    }





@IBAction func eksibuton(_ sender: Any) {
    if (baslangicDegeri > 0 ) {
        baslangicDegeri -= 1
        tarhanaadetlabel.text = String(baslangicDegeri)
        tarhanaadetlabel.text = "ADET : \(baslangicDegeri) "
    }
}


@IBAction func artibuton(_ sender: Any) {

    baslangicDegeri += 1
    tarhanaadetlabel.text = String(baslangicDegeri)
    tarhanaadetlabel.text = "ADET : \(baslangicDegeri) "
    }
Mert çevik
  • 3
  • 1
  • 5
  • Dispatch the reload on the main queue. UI operations must be performed on the main queue. – Paulw11 Apr 26 '18 at 13:46
  • just put all code in DispatchQueue.main.async including your for loop – Hitesh Surani Apr 26 '18 at 14:12
  • Please share the sample ? – Mert çevik Apr 26 '18 at 14:32
  • i tried but not working – Mert çevik Apr 26 '18 at 15:08
  • Please review [this question](https://stackoverflow.com/questions/39178165/firebase-asynchronous-function-whats-in-the-background-queue-and-whats-not/39183023#39183023) and [Update the UI](https://stackoverflow.com/questions/47490768/how-does-dispatch-main-async-update-the-ui/47490847#47490847). The bottom line is you don't need DispatchQueue to update the ui within the firebase closure as it's already running on the main thread. – Jay Apr 27 '18 at 17:52
  • To fix your issue, the tableView needs to who who it's delegate and dataSource are. So in your viewDidLoad function, add *self.tableView.delegate = self* and *self.tableView.dataSource = self* – Jay Apr 27 '18 at 17:56
  • As a side note, you may want to consider creating a singlePost class or structure, and pass the data from Firebase to populate it, then you can just work with one array for all your data. something like *post = Post(by: by_someone, text: the_text, image: the_image)* and then *self.postsArray.append(post)* – Jay Apr 27 '18 at 17:59

1 Answers1

1

My guess is that your Firebase childAdded function's completion handler is being called on a background thread. You need to issue the reloadData call on the main thread. Try using dispatchAsync:

DispatchQueue.main.async {
            self.tableView.reloadData()
}
Duncan C
  • 128,072
  • 22
  • 173
  • 272
  • My problem still continues :( – Mert çevik Apr 26 '18 at 13:59
  • 1
    @Mertçevik Hey I don't know if you put all of your code here but where did you set the `delegate` and `dataSource` of your tableview? Also the answer above to put the reload on the main queue is important. – congsun Apr 26 '18 at 15:13
  • I'm not sure if FireBase's completion handlers are run on the main thread or not. IF they are then this fix will have no effect, and based on some Googling I did it looks like the completion handlers **are** run on the main thread. – Duncan C Apr 26 '18 at 17:04
  • @congsun i putted appdelegate.swift – Mert çevik Apr 26 '18 at 18:49
  • @Mertçevik No I mean where do you set the `tableView.delegate = self` and `tableView.dataSource = self`? Without that the tableView won't be able to find the data – congsun Apr 26 '18 at 18:52
  • @congsun Maybe like this ? I shared this add data part – Mert çevik Apr 26 '18 at 19:22
  • No - you don't need this within a Firebase closure. See my comments on the question – Jay Apr 27 '18 at 17:53