Reputation: 45
I have spend so much time to find a solution with the documentation from Firebase without any success. I using Swift 5.3 and Firestore and have the following code:
func readFlights() {
Spinner.startAnimating()
let myquery = db.collection("flight").limit(to: 25).whereField("Userid", isEqualTo: userID).order(by: "DateDB", descending: true)
.order(by: "Start", descending: true)
myquery.getDocuments() { (querySnapshot, err) in
if let err = err {
print("Error getting documents: \(err)")
} else {
for document in querySnapshot!.documents {
self.prefixArray.append(document.get("Prefix") as! String)
self.dateArray.append(document.get("Date") as! String)
self.startArray.append(document.get("Start") as! String)
self.stopArray.append(document.get("Stop") as! String)
self.landingArray.append(document.get("Landing") as! String)
self.takeOffArray.append(document.get("Takeoff") as! String)
self.flightTimeArray.append(document.get("FlightTime") as! String)
self.engineTimeArray.append(document.get("EngineTime") as! String)
self.idArray.append(document.get("id") as! String)
self.destinationArray.append(document.get("Destination") as! String)
self.originArray.append(document.get("Origin") as! String)
self.informationArray.append(document.get("Addinfo") as! String)
self.rulesArray.append(document.get("VFRIFR") as! Int)
self.pilotCopilotArray.append(document.get("PilotoCopiloto") as! Int)
self.engineArray.append(document.get("MnteMlte") as! Int)
self.dayNightArray.append(document.get("DayNight") as! Int)
}
DispatchQueue.main.async{
self.tabelView.reloadData()
self.Spinner.stopAnimating()
}
}
}
working fine but I need to include in this code pagination. That means when I received the first 25 records from Firestore and I slip down in the list with my finger so I want after the latest record he load 25 records more and show them.
I would appreciate your help. Thank you
Upvotes: 0
Views: 186
Reputation: 12385
First, create a document cursor that is an instance property of the view/view controller:
var cursor: DocumentSnapshot?
let pageSize = 25 // for convenience
Second, apply the page size to the query:
let myquery = db.collection("flight").limit(to: pageSize).whereField("Userid", isEqualTo: userID).order(by: "DateDB", descending: true).order(by: "Start", descending: true)
Third, whenever you receive a snapshot from Firestore, update the cursor at some point in the return (ideally, after you've unwrapped the snapshot and before you've parsed the documents):
func getData() {
myquery.getDocuments(completion: { (snapshot, error) in
...
if snapshot.count < pageSize {
/* this return had less than 25 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 25 documents, therefore
there may be more documents to fetch which makes
the last document in this snapshot the cursor */
self.cursor = snapshot.documents.last
}
...
})
}
Finally, whenever the user scrolls to the bottom, fetch another page using the cursor:
func continueData() {
guard let cursor = cursor else {
return // no cursor, exit
}
myquery.start(afterDocument: cursor).getDocuments(completion: { (snapshot, error) in
...
// always update the cursor whenever Firestore returns
if snapshot.count < self.pageSize {
self.cursor = nil
} else {
self.cursor = snapshot.documents.last
}
...
})
}
For a fluid user experience, you will need to greatly refine this code, but this is the foundation from which you can paginate Firestore. You can also paginate in Firestore using a document offset (instead of a document cursor) but this is to be avoided (refer to documentation for the reasons).
Upvotes: 1
Reputation: 472
By using UITableViewDelegate, u can call the function. Each time when you scroll to the bottom, it will check the max of your limit and if the condition is true, then fetch data again.
func tableView(_ tableView: UITableView, willDisplay cell: UITableViewCell, forRowAt indexPath: IndexPath) {
let lastItem = self.array.count - 1
if indexPath.row == lastItem {
if limit < max_limit {
limit += 25
//Get data from Server
readFlights(limit:Int)
}
}
}
The max_limit means the total amount of limits, usually, it returned by server in meta
Upvotes: 0
Reputation: 556
You can use awesome solution from: https://github.com/pronebird/UIScrollView-InfiniteScroll
For your example:
tableView.addInfiniteScroll { (tableView) -> Void in
readFlights("offset if need")
tableView.finishInfiniteScroll()
}
Upvotes: 0