TableView未在Swift中显示从Firebase Cloud Firestore检索到的数据

huangapple go评论73阅读模式
英文:

TableView not Showing the Retrieved Firebase Cloud Firestore Data in Swift

问题

我正在创建一个虚拟社交媒体应用,但UITableView的行为不是我预期的。在数据检索操作后,UITableView没有显示获取的内容。以下是我的FeedViewController的代码:

import UIKit
import FirebaseFirestore

class FeedViewController: UIViewController, UITableViewDelegate, UITableViewDataSource  {
    
    @IBOutlet weak var tableView: UITableView!
    
    var postArray = [[String: Any]]()
    
    override func viewDidLoad() {
        super.viewDidLoad()
        tableView.delegate = self
        tableView.dataSource = self
        getDataFromFirestore(){
            print("self.tableView.reloadData() called from viewDidLoad()")
            self.tableView.reloadData()
        }
    }
    
    override func viewDidAppear(_ animated: Bool) {
        print("self.tableView.reloadData() called from viewDidAppear()")
        self.tableView.reloadData()
    }
    
    func getDataFromFirestore(completion: @escaping() -> Void){
        let ref = Firestore.firestore().collection("posts")
        ref.addSnapshotListener { snapshot, error in
            if error != nil {
                self.makeAlert(title: "Error", message: error?.localizedDescription ?? "An error occurred during the process.")
            } else {
                if !(snapshot?.isEmpty ?? true) {
                    for doc in snapshot!.documents {
                        var dict = [String: Any]()
                        dict["userID"] = doc.get("userID") as? String
                        dict["comment"] = doc.get("comment") as? String
                        dict["imageURL"] = doc.get("imageURL") as? String
                        dict["likes"] = doc.get("likes") as? String
                        self.postArray.append(dict)
                    }
                }
                print("self.postArray.count been accessed from getDataFromFirestore():  \(self.postArray.count)")
            }
        }
        completion()
    }
    
    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let cell = tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath) as! FeedCell
        cell.lblUserEmail.text = self.postArray[indexPath.row]["userID"] as! String? ?? ""
        cell.lblLikes.text = self.postArray[indexPath.row]["likes"] as! String? ?? ""
        cell.lblUserComment.text = self.postArray[indexPath.row]["comment"] as! String? ?? ""
        return cell
    }
    
    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        print("self.postArray.count been accessed from numberOfRowsInSection:  \(self.postArray.count)")
        return postArray.count
    }
    
    func makeAlert(title: String, message: String) {
            let controller = UIAlertController(title: title, message: message, preferredStyle: UIAlertController.Style.alert)
            let action = UIAlertAction(title: "OK", style: UIAlertAction.Style.default)
            controller.addAction(action)
            self.present(controller, animated: true)
        }
}

控制台输出:

self.tableView.reloadData() called from viewDidLoad()
self.postArray.count been accessed from numberOfRowsInSection:  0
self.postArray.count been accessed from numberOfRowsInSection:  0
self.postArray.count been accessed from numberOfRowsInSection:  0
self.tableView.reloadData() called from viewDidAppear()
self.postArray.count been accessed from numberOfRowsInSection:  0
self.postArray.count been accessed from getDataFromFirestore():  1

这是我的UITableViewCell的代码:

import UIKit

class FeedCell: UITableViewCell {

    @IBOutlet weak var lblUserComment: UILabel!
    @IBOutlet weak var lblUserEmail: UILabel!
    @IBOutlet weak var imgView: UIImageView!
    @IBOutlet weak var lblLikes: UILabel!

    
    override func awakeFromNib() {
        super.awakeFromNib()
        // 初始化代码
    }

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

        // 配置选定的状态
    }

    @IBAction func btnLikeClicked(_ sender: Any) {
    }
}

Firestore中的数据:
TableView未在Swift中显示从Firebase Cloud Firestore检索到的数据

屏幕输出(空白且无数据):

TableView未在Swift中显示从Firebase Cloud Firestore检索到的数据

英文:

I am creating a dummy social media app, but UITableView's behavior is not what I expected. After data retrieve operation, the UITableView is not showing the fetched content. Here is my FeedViewController's code:

import UIKit
import FirebaseFirestore
class FeedViewController: UIViewController, UITableViewDelegate, UITableViewDataSource  {
@IBOutlet weak var tableView: UITableView!
var postArray = [[String: Any]]()
override func viewDidLoad() {
super.viewDidLoad()
tableView.delegate = self
tableView.dataSource = self
getDataFromFirestore(){
print("self.tableView.reloadData() called from viewDidLoad()")
self.tableView.reloadData()
}
}
override func viewDidAppear(_ animated: Bool) {
print("self.tableView.reloadData() called from viewDidAppear()")
self.tableView.reloadData()
}
func getDataFromFirestore(completion: @escaping() -> Void){
let ref = Firestore.firestore().collection("posts")
ref.addSnapshotListener { snapshot, error in
if error != nil {
self.makeAlert(title: "Error", message: error?.localizedDescription ?? "An error occoured during the process.")
} else {
if !(snapshot?.isEmpty ?? true) {
for doc in snapshot!.documents {
var dict = [String: Any]()
dict["userID"] = doc.get("userID") as? String
dict["comment"] = doc.get("comment") as? String
dict["imageURL"] = doc.get("imageURL") as? String
dict["likes"] = doc.get("likes") as? String
self.postArray.append(dict)
}
}
print("self.postArray.count been accessed from getDataFromFirestore():  \(self.postArray.count)")
}
}
completion()
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath) as! FeedCell
cell.lblUserEmail.text = self.postArray[indexPath.row]["userID"] as! String? ?? ""
cell.lblLikes.text = self.postArray[indexPath.row]["likes"] as! String? ?? ""
cell.lblUserComment.text = self.postArray[indexPath.row]["comment"] as! String? ?? ""
return cell
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
print("self.postArray.count been accessed from numberOfRowsInSection:  \(self.postArray.count)")
return postArray.count
}
func makeAlert(title: String, message: String) {
let controller = UIAlertController(title: title, message: message, preferredStyle: UIAlertController.Style.alert)
let action = UIAlertAction(title: "OK", style: UIAlertAction.Style.default)
controller.addAction(action)
self.present(controller, animated: true)
}
}

Console Output:

self.tableView.reloadData() called from viewDidLoad()
self.postArray.count been accessed from numberOfRowsInSection:  0
self.postArray.count been accessed from numberOfRowsInSection:  0
self.postArray.count been accessed from numberOfRowsInSection:  0
self.tableView.reloadData() called from viewDidAppear()
self.postArray.count been accessed from numberOfRowsInSection:  0
self.postArray.count been accessed from getDataFromFirestore():  1

Here is my UITableViewCell's code:

import UIKit
class FeedCell: UITableViewCell {
@IBOutlet weak var lblUserComment: UILabel!
@IBOutlet weak var lblUserEmail: UILabel!
@IBOutlet weak var imgView: UIImageView!
@IBOutlet weak var lblLikes: UILabel!
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
}
@IBAction func btnLikeClicked(_ sender: Any) {
}
}

Data in Firestore:
TableView未在Swift中显示从Firebase Cloud Firestore检索到的数据

The screen output (blank and no data):

TableView未在Swift中显示从Firebase Cloud Firestore检索到的数据

答案1

得分: 1

你正在在监听器之外调用完成闭包,所以完成操作将不会等待响应并重新加载表格视图。

func getDataFromFirestore(completion: @escaping() -> Void){
    let ref = Firestore.firestore().collection("posts")
    ref.addSnapshotListener { snapshot, error in
        if error != nil {
            self.makeAlert(title: "Error", message: error?.localizedDescription ?? "An error occurred during the process.")
        } else {
            if !(snapshot?.isEmpty ?? true) {
                for doc in snapshot!.documents {
                    var dict = [String: Any]()
                    dict["userID"] = doc.get("userID") as? String
                    dict["comment"] = doc.get("comment") as? String
                    dict["imageURL"] = doc.get("imageURL") as? String
                    dict["likes"] = doc.get("likes") as? String
                    self.postArray.append(dict)
                }
            }
            print("self.postArray.count been accessed from getDataFromFirestore():  \(self.postArray.count)")
            completion()
        }
    }
}

像这样做,享受吧 TableView未在Swift中显示从Firebase Cloud Firestore检索到的数据

英文:

you are calling completion outside the listener. so completion will not wait for response and reload tableview.

func getDataFromFirestore(completion: @escaping() -> Void){
let ref = Firestore.firestore().collection("posts")
ref.addSnapshotListener { snapshot, error in
if error != nil {
self.makeAlert(title: "Error", message: error?.localizedDescription ?? "An error occoured during the process.")
} else {
if !(snapshot?.isEmpty ?? true) {
for doc in snapshot!.documents {
var dict = [String: Any]()
dict["userID"] = doc.get("userID") as? String
dict["comment"] = doc.get("comment") as? String
dict["imageURL"] = doc.get("imageURL") as? String
dict["likes"] = doc.get("likes") as? String
self.postArray.append(dict)
}
}
print("self.postArray.count been accessed from getDataFromFirestore():  \(self.postArray.count)")
completion()
}
} 
}

Do it like this and enjoy TableView未在Swift中显示从Firebase Cloud Firestore检索到的数据

huangapple
  • 本文由 发表于 2023年7月20日 18:49:57
  • 转载请务必保留本文链接:https://go.coder-hub.com/76729117.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定