使用 SnapShotListener 从 FirebaseFirestore 读取数据后如何刷新我的 UITableView?
How do refresh my UITableView after reading data from FirebaseFirestore with a SnapShotListener?
更新在底部。
我遵循了 this Apple iOS Dev Tutorial 的 UI 套件部分,直至并包括保存新提醒部分。教程在每个部分的开头提供了完整的代码供下载。
但是,我想让 FirebaseFirestore 参与进来。我还有其他一些 Firestore 项目可以运行,但我一直认为我做的事情不太正确,所以我一直在寻找更好的例子来学习。
这就是我找到 Peter Friese 的 3 部分 YT 系列“Build a To-Do list with Swift UI and Firebase”的方式。虽然我没有使用 SwiftUI,但我认为 Firestore 代码应该只需进行一些更改即可工作,因为他创建了一个存储库,其唯一功能是在应用程序和 Firestore 之间进行交互。不涉及 UI。所以,按照他的例子,我添加了一个 ReminderRepository
.
它不起作用,但我所以接近。 UITableView
看起来是空的,但我知道正在加载记录。
在调试器中单步执行,我看到第一次调用 numberOfRowsInSection
时,数据还没有从 Firestore 加载,所以它是 returns 0。但是,最终代码 确实 加载数据。我可以在映射时看到每个 Reminder
,最后,所有文档都加载到 reminderRepository.reminders
属性.
但我不知道如何获得 loadData()
以便稍后重新加载 table。
ReminderRepository.swift
class ReminderRepository {
let remindersCollection = Firestore.firestore()
.collection("reminders").order(by: "date")
var reminders = [Reminder]()
init() {
loadData()
}
func loadData() {
print ("loadData")
remindersCollection.addSnapshotListener { (querySnapshot, error) in
if let querySnapshot = querySnapshot {
self.reminders = querySnapshot.documents.compactMap { document in
do {
let reminder = try document.data(as: Reminder.self)
print ("loadData: ", reminder?.title ?? "Unknown")
return reminder
} catch {
print (error)
}
return nil
}
}
print ("loadData: ", self.reminders.count)
}
}
}
与 Apple 代码的唯一区别是在 ListDataSource.swift 文件中,我添加了:
var remindersRepository: ReminderRepository
override init() {
remindersRepository = ReminderRepository()
}
并且该文件中的所有 reminders
引用都已更改为
remindersRepository.reminders
.
我需要为 init()
提供回调吗?如何?我对这件事还是有点怀疑。
更新:不是完整的信用解决方案,但越来越接近。
我在 ReminderListViewController.viewDidLoad()
以及引用的函数中添加了两行:
refreshControl = UIRefreshControl()
refreshControl?.addTarget(self, action: #selector(refreshTournaments(_:)), for: .valueChanged)
@objc
private func refreshTournaments(_ sender: Any) {
tableView.reloadData()
refreshControl?.endRefreshing()
}
现在,当我盯着最初的空白table,我从顶部下拉,它会刷新。现在,如何让它自动执行此操作?
请尝试将 var reminders = [Reminder]()
更改为
var reminders : [Reminder] = []{
didSet {
self.tableview.reloadData()
}
}
首先创建一些 ReminderRepositoryDelegate
协议,它将处理您的控制器部分(在您的情况下 ReminderListDataSource
)和您的模型部分(在您的情况下 ReminderRepository
)之间的通信。然后设置reminder
后通过委派controller加载数据。以下是一些步骤:
正在创建委托协议。
protocol ReminderRepositoryDelegate: AnyObject {
func reloadYourData()
}
符合ReminderListDataSource
委托协议:
class ReminderListDataSource: UITableViewDataSource, ReminderRepositoryDelegate {
func reloadYourData() {
self.tableView.reloadData()
}
}
将委托弱变量添加到 ReminderRepository 中,它将弱化您的控制器。
class ReminderRepository {
let remindersCollection = Firestore.firestore()
.collection("reminders").order(by: "date")
var reminders = [Reminder]()
weak var delegate: ReminderRepositoryDelegate?
init() {
loadData()
}
}
在创建ReminderRepository
时将ReminderListDataSource
设置为委托
override init() {
remindersRepository = ReminderRepository()
remindersRepository.delegate = self
}
设置提醒后加载数据
func loadData() {
print ("loadData")
remindersCollection.addSnapshotListener { (querySnapshot, error) in
if let querySnapshot = querySnapshot {
self.reminders = querySnapshot.documents.compactMap { document in
do {
let reminder = try document.data(as: Reminder.self)
print ("loadData: ", reminder?.title ?? "Unknown")
delegate?.reloadYourData()
return reminder
} catch {
print (error)
}
return nil
}
}
print ("loadData: ", self.reminders.count)
}
}
更新在底部。
我遵循了 this Apple iOS Dev Tutorial 的 UI 套件部分,直至并包括保存新提醒部分。教程在每个部分的开头提供了完整的代码供下载。
但是,我想让 FirebaseFirestore 参与进来。我还有其他一些 Firestore 项目可以运行,但我一直认为我做的事情不太正确,所以我一直在寻找更好的例子来学习。
这就是我找到 Peter Friese 的 3 部分 YT 系列“Build a To-Do list with Swift UI and Firebase”的方式。虽然我没有使用 SwiftUI,但我认为 Firestore 代码应该只需进行一些更改即可工作,因为他创建了一个存储库,其唯一功能是在应用程序和 Firestore 之间进行交互。不涉及 UI。所以,按照他的例子,我添加了一个 ReminderRepository
.
它不起作用,但我所以接近。 UITableView
看起来是空的,但我知道正在加载记录。
在调试器中单步执行,我看到第一次调用 numberOfRowsInSection
时,数据还没有从 Firestore 加载,所以它是 returns 0。但是,最终代码 确实 加载数据。我可以在映射时看到每个 Reminder
,最后,所有文档都加载到 reminderRepository.reminders
属性.
但我不知道如何获得 loadData()
以便稍后重新加载 table。
ReminderRepository.swift
class ReminderRepository {
let remindersCollection = Firestore.firestore()
.collection("reminders").order(by: "date")
var reminders = [Reminder]()
init() {
loadData()
}
func loadData() {
print ("loadData")
remindersCollection.addSnapshotListener { (querySnapshot, error) in
if let querySnapshot = querySnapshot {
self.reminders = querySnapshot.documents.compactMap { document in
do {
let reminder = try document.data(as: Reminder.self)
print ("loadData: ", reminder?.title ?? "Unknown")
return reminder
} catch {
print (error)
}
return nil
}
}
print ("loadData: ", self.reminders.count)
}
}
}
与 Apple 代码的唯一区别是在 ListDataSource.swift 文件中,我添加了:
var remindersRepository: ReminderRepository
override init() {
remindersRepository = ReminderRepository()
}
并且该文件中的所有 reminders
引用都已更改为
remindersRepository.reminders
.
我需要为 init()
提供回调吗?如何?我对这件事还是有点怀疑。
更新:不是完整的信用解决方案,但越来越接近。
我在 ReminderListViewController.viewDidLoad()
以及引用的函数中添加了两行:
refreshControl = UIRefreshControl()
refreshControl?.addTarget(self, action: #selector(refreshTournaments(_:)), for: .valueChanged)
@objc
private func refreshTournaments(_ sender: Any) {
tableView.reloadData()
refreshControl?.endRefreshing()
}
现在,当我盯着最初的空白table,我从顶部下拉,它会刷新。现在,如何让它自动执行此操作?
请尝试将 var reminders = [Reminder]()
更改为
var reminders : [Reminder] = []{
didSet {
self.tableview.reloadData()
}
}
首先创建一些 ReminderRepositoryDelegate
协议,它将处理您的控制器部分(在您的情况下 ReminderListDataSource
)和您的模型部分(在您的情况下 ReminderRepository
)之间的通信。然后设置reminder
后通过委派controller加载数据。以下是一些步骤:
正在创建委托协议。
protocol ReminderRepositoryDelegate: AnyObject { func reloadYourData()
}
符合
ReminderListDataSource
委托协议:class ReminderListDataSource: UITableViewDataSource, ReminderRepositoryDelegate { func reloadYourData() { self.tableView.reloadData() }
}
将委托弱变量添加到 ReminderRepository 中,它将弱化您的控制器。
class ReminderRepository { let remindersCollection = Firestore.firestore() .collection("reminders").order(by: "date") var reminders = [Reminder]() weak var delegate: ReminderRepositoryDelegate? init() { loadData() }
}
在创建
时将ReminderRepository
ReminderListDataSource
设置为委托override init() { remindersRepository = ReminderRepository() remindersRepository.delegate = self
}
设置提醒后加载数据
func loadData() { print ("loadData") remindersCollection.addSnapshotListener { (querySnapshot, error) in if let querySnapshot = querySnapshot { self.reminders = querySnapshot.documents.compactMap { document in do { let reminder = try document.data(as: Reminder.self) print ("loadData: ", reminder?.title ?? "Unknown") delegate?.reloadYourData() return reminder } catch { print (error) } return nil } } print ("loadData: ", self.reminders.count) }
}