How to Create Infinite Scroll in UITableView
Simple way to paginate your TableView based on API data
Overview
The rise of social media platforms such as Facebook and Twitter have had a significant impact on the world today. People appear to have a habit of scrolling through their feeds all day, looking at various information and stories.
A feed page is a common feature in every social app that allows users to scroll indefinitely. In this article, we will learn how to fetch large amounts of data with pagination. We will be using GitHub API to simulate the endless data request.
GitHub provides an API in which some of the endpoints are public and the data can be accessed without requiring authentication, such as getting a list of users and public repositories.
What Will We Build?
We are going to create a simple app that has the following capabilities.
1. Able to call API and scroll UITableView with pagination.
We will use Github API to get a list of users. It contains all GitHub users since the beginning it was founded.
In the result above, I used the Network Conditioner tool to create an “Edge” connection so that we can see the loading process (a High-speed network will be very fast and seamless loading).
2. Handle request error
I then changed to “100% Loss” to show error handling on failed data fetches. See my previous article on how to simulate multiple network conditions.
Coding Begins
1. Create New UIKit Project
In this project, we will use UIKit and Storyboard.
2. Insert Navigation Controller (Optional)
After creating the project, embed the default ViewController with Navigation View Controller. Select Main.storyboard, then select the top menu Editor > Embed in > Navigation Controller.
3. Insert UITableView to Storyboard
Open the storyboard and insert UITableView. Then pin the constraint to the edges of superview. Don’t forget to link the UITableView as an IBOutlet in ViewController class.
4. Create User Model
Create a new model file called User.swift and add this code. We only get the id, name, and avatarUrl from the JSON object. In this project, we will only display the name as for a quick example.
5. Create API Service Manager
Create a new file called “GithubAPIManager.swift” to handle API requests. It is just a common API request using URLSession with dataTask()
method. In that file, insert the below code.
- Create an error type to be used in the completion handler
- Construct proper API URL with parameters
- Create
URLRequest
with a timeout of 10 seconds.
5. Setup TableView and API Integration
Open your ViewController file and add the below code. Also at the bottom of code, we add some of the TableView datasource methods (delegate methods will be used in the next step).
- Add
users
variable to store data from API and whenever it is set, TableView will immediately reload its content. setupView()
, a simple setup on TableView. We need to add.delegate
later.- A function to call our API service and handle data received.
- Add a default TableView Cell to display the name and row number.
After adding the code, run your project and you should get the simple TableView list as shown in the below image. You will get exactly 30 rows in the TableView as the default perPage
parameter and not yet able to paginate.
6. Setup Pagination
Great. We are done setting up the base of the project. Now, we need to make some updates to make sure our user list can be scrolled endlessly. Update our ViewController class as follows and see the explanation of each code change.
The following is the explanation of the amendments.
- We added new enum of
TableSection
. Our TableView will have two sections. The first is to keep the same user list while the second one is to keep the loader cell. - Two more variables are added.
pageLimit
is used to keep the constant of limit objects requested andcurrentLastId
is used to store id of the lastUser
object in theusers
array. ThecurrentLastId
will be used when fetching the next page API by providing thesince
parameter with the last id that we already fetched. - Assign TableView delegate to current ViewController to enable use of
willDisplay
method call. - Update fetchData with completion callback to receive the success or failure status.
- Change
=
to.append
method to keep theusers
array expanding instead of replacing. - Update
completion()
with success status. - Added
numberOfSections
since we will keep two section, as mentioned in point number 1. numberOfRowsInSection
is now depending on the section. Also, only if the users data size is morepageLimit
, then we will show the loading cell.- Simply update cell text to name for user list and “Loading.. ” for the second section.
- This is the important part where the loader cell will appear and the API service will start fetching new data (next page).
- In the previous point, in the
willDisplay
method, thehideBottomLoader()
will be called when the error happens. Yeah, we are done! Try to run the code and keep scrolling to the bottom until you reach your name 😆.
Potential Bug
There is a potential bug that might happen when the network connection is slow. When users reach the bottom loader cell, they may continue to scroll up and down in order to send multiple API requests with the same currentLastId
. As a result, the success data will be redundant.
It’s you homework to fix this issue 🤭
Don’t panic! The simplest solution is to compare the currentLastId
each time the request is sent. Make sure to check the currentLastId
is different from the previous requests. Yes, that’s it.
Project Completed
Congratulations! We have completed all of the steps and the project is now ready and works perfectly. The entire source code is available for download from my GitHub repository. You may try implementing it into your projects and perhaps improving the code by developing a subclass or UITableView extension, so that it can be reused in other view controllers.
Thanks for reading. Happy coding!