Ali*_*dil 5 pagination ios firebase swift google-cloud-firestore
使用我的应用程序,我尝试使用下面的代码从Firestore分页我的数据(每页10个帖子),
import UIKit
import FirebaseFirestore
class Home: UITableViewController {
var postArray = [postObject]()
let db = Firestore.firestore()
var page : DocumentSnapshot? = nil
let pagingSpinner = UIActivityIndicatorView(activityIndicatorStyle: .gray)
override func viewDidLoad() {
super.viewDidLoad()
loadFirstPage()
}
func loadFirstPage(){
// Get the first 10 posts
db.collection("POSTS").limit(to: 10).addSnapshotListener { (snapshot, error) in
if snapshot != nil {
self.postArray = (snapshot?.documents.flatMap({postObject(dec : $0.data())}))!
// Save the last Document
self.page = snapshot?.documents.last
self.tableView.reloadData()
}
}
}
func loadNextPage(){
// get the next 10 posts
db.collection("POSTS").limit(to: 10).start(afterDocument: page!).addSnapshotListener { (snapshot, error) in
if snapshot != nil {
for doc in (snapshot?.documents)! {
self.postArray.append(postObject(dec: doc.data()))
}
self.page = snapshot?.documents.last
self.tableView.reloadData()
}
}
}
override func numberOfSections(in tableView: UITableView) -> Int {
return 1
}
override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return postArray.count
}
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "postCell", for: indexPath) as? postCell
// display data
cell?.textLabel?.text = postArray[indexPath.row].name
return cell!
}
override func tableView(_ tableView: UITableView, willDisplay cell: UITableViewCell, forRowAt indexPath: IndexPath) {
// check index to load next page
if indexPath.row < (self.postArray.count){
pagingSpinner.startAnimating()
pagingSpinner.color = UIColor.red
pagingSpinner.hidesWhenStopped = true
tableView.tableFooterView = pagingSpinner
loadNextPage()
}
}
}
Run Code Online (Sandbox Code Playgroud)
但我遇到了以下问题:
我想知道为什么会发生这种情况虽然我将最后一个Sanpshot文档保存为分页光标!是否有更好的原因来实现Swift的分页
getDocuments如果我们手动(使用)而不是自动(使用)获取文档,则使用 Swift 在 Firestore 中分页非常简单addSnapshotListener。
我认为为了可读性,将数据加载(第一页)与连续数据(附加页面)分开是明智的。显然你必须自己构建firestoreQuery一个对象。Query
class SomeViewController: UIViewController {
private var cursor: DocumentSnapshot?
private let pageSize = 10 // use this for the document-limit value in the query
private var dataMayContinue = true
/* This method grabs the first page of documents. */
private func loadData() {
firestoreQuery.getDocuments(completion: { (snapshot, error) in
...
/* At some point after you've unwrapped the snapshot,
manage the cursor. */
if snapshot.count < pageSize {
/* This return had less than 10 documents, therefore
there are no more possible documents to fetch and
thus there is no cursor. */
self.cursor = nil
} else {
/* This return had at least 10 documents, therefore
there may be more documents to fetch which makes
the last document in this snapshot the cursor. */
self.cursor = snapshot.documents.last
}
...
})
}
/* This method continues to paginate documents. */
private func continueData() {
guard dataMayContinue,
let cursor = cursor else {
return
}
dataMayContinue = false /* Because scrolling to bottom will cause this method to be called
in rapid succession, use a boolean flag to limit this method
to one call. */
firestoreQuery.start(afterDocument: cursor).getDocuments(completion: { (snapshot, error) in
...
/* Always update the cursor whenever Firestore returns
whether it's loading data or continuing data. */
if snapshot.count < self.pageSize {
self.cursor = nil
} else {
self.cursor = snapshot.documents.last
}
...
/* Whenever we exit this method, reset dataMayContinue to true. */
})
}
}
/* Let's assume you paginate with infinite scroll which means continuing data
when the user scrolls to the bottom of the table or collection view. */
extension SomeViewController {
/* Standard scroll-view delegate */
func scrollViewDidScroll(_ scrollView: UIScrollView) {
let contentSize = scrollView.contentSize.height
if contentSize - scrollView.contentOffset.y <= scrollView.bounds.height {
didScrollToBottom()
}
}
private func didScrollToBottom() {
continueData()
}
}
Run Code Online (Sandbox Code Playgroud)
我们仍然可以使用快照侦听器进行分页,但需要更多步骤。这是因为当快照侦听器返回时,它将返回单页文档,如果用户已对多个页面进行分页,则更新会将用户重置回单页。补救措施是跟踪屏幕上呈现的页面数量,并在快照侦听器返回时在刷新 UI 之前加载用户下方的页面数量。然而,除此之外还有其他步骤,例如在 UI 刷新过程中处理新的快照返回;这种竞争条件需要严格的序列化,这可能需要也可能不需要信号量或其他有效的东西。
| 归档时间: |
|
| 查看次数: |
1207 次 |
| 最近记录: |