英文:
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) {
}
}
屏幕输出(空白且无数据):
英文:
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) {
}
}
The screen output (blank and no data):
答案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()
}
}
}
像这样做,享受吧
英文:
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
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论