How to Implement Pagination in iOS

Hello everyone!

In this article, I'm going to go over how you can easily set up pagination on your iOS app.

What is Pagination

When requesting an API you may receive a lot of data that you don't necessarily need to show at that moment. Why would you need to receive 100 elements from the API if you only need to show 5 elements on the screen?

That's where pagination comes in. Through query parameters, you can specifically request which page you want to receive and how many elements the remote API should return. There are many types of paginations such as OffSet Pagination, Keyset Pagination and Page Base Pagination [1]. In this article, I'm going to use Page Base Pagination but I assure you that most of the logic is similar if you choose other pagination techniques.

Page Base Pagination

This pagination technique involves using a "page" parameter to specify the desired page number. You request a specific page of data with usually a limit (how many elements do you want) and the API responds with the corresponding page [2].

Here's one example of an API that accepts page base pagination with a limit:

https://randomuser.me/api/?page=1&results=5

The random user API allows page-based pagination with a limit parameter (called results in this case).

Demonstration

To explain how to handle the pagination in iOS I'm going to create a use case and implement it using UIKit and a simple Table View.

Use Case

As a User, I want to be able to scroll through a list and see data on the screen.

When I scroll down I should see a loading indicator and new elements popping up on the screen.

How Does Pagination Work

Before diving into code it's important to understand how this all comes together. We understand how the API is handled on their side but we don't know how we're going to do it on iOS.

First, from the Use Case, we know that when the user scrolls down more cells should appear. This means that we're going to fire another request to the API when we reach the end of the list.

But how will we keep track of which page we're on? It should be on our side as consumers to have some sort of currentPage to know which page we need to request to the API.

First, on the iOS side, it should request the API using the query parameter that I referred to before. If this is the first request, then the current page requested is 1 and the limit could be 5 (this depends on the project).

I've created a simple diagram to explain how everything comes together.

When the API replies successfully then we should increment the current page value.

But where should this happen?

If you're using a table view to list the elements there is a method called tableView(_:prefetchRowsAt:) which, according to Apple's documentation [3]:

Instructs your prefetch data source object to begin preparing data for the cells at the supplied index paths.

You can check for the index in this method and check if it's the last cell selected (through the index).

Something along the lines of:

public override func tableView(
    _ tableView: UITableView,
    prefetchRowsAt indexPaths: [IndexPath]
)
         if let lastIndexPath = indexPaths.last, lastIndexPath.row == tableModel.count - 1 && !isFetching {

            APICall(withCurrentPageNumber: currentPage)
            isFetching = true
        }
    }

Thank you to @Adriano Paladini on LinkedIn for pointing out that prefetch rows are better since we don't want to keep calling the method for any loaded cell.

I've added the isFetching flag to make sure there is only one request being made at a time.

You can set the flag to false again when the API replies with the result.

This is what is happening:

That's it. It's the full explanation of how you can easily implement a pager using tableView.

Thank you for reading, if you want to support my work please follow me on LinkedIn, X and Github. 🙏🏻

Glossary

If you're not familiar with some of the keywords that I referred to in this article, I added this Glossary section to make things easier.

  1. Query Parameter: A query parameter is specific instructions to the API about what you're looking for, helping them find it faster.
  2. API: Service that takes a request and communicates it to the kitchen (the system that provides the service or data you want). It helps different software systems talk to each other and share information or functionality.
  3. Consumer: Any component that uses the API. An iOS app consumes data from an API for example.

References

[1] https://www.merge.dev/blog/rest-api-pagination

[2]https://www.getknit.dev/blog/api-pagination-techniques

[3]https://developer.apple.com/documentation/uikit/uitableviewdelegate/1614883-tableview