How to paginate YouTube Videos with SwiftUI (Part2)

How to paginate YouTube Videos with SwiftUI (Part2)


2 min read

In the previous post for the Youtube series, I shared the way to fetch YouTube videos from YouTube API with SwiftUI. This app still lacks its functionality because it only has 15 Dragon ball videos. Generally, the reason for the pagination is to prevent unnecessary API calls which may cost you a lot. In this post, I want to share how to fetch more videos by pagination, which is calling another API by scrolling to the bottom.

I’ve already built the view with the search text field and the function that fetches videos in the previous postso please read if you haven't checked yet.

Let’s add logic for the pagination. Whenever reaching at the last item of the list, I want to call another API call, fetching 15 more videos. The reason I put (youtubeVideoViewModel.youtubeSearchLists.count - 1) == index is that I don’t want to call another API by scrolling back.

struct ContentView: View {

    @ObservedObject var youtubeVideoViewModel = YoutubeVideoViewModel()
    @State private var searchText = ""

    var body: some View {
        NavigationView {
            VStack {
                TextField("Search", text: $searchText) { isEditing in
                } onCommit: {
                    youtubeVideoViewModel.fetchVideoWithSearch(searchText: searchText)
                List {
                    Group {
                        ForEach(0..<youtubeVideoViewModel.youtubeSearchLists.count, id: \.self) { index in
                            ForEach(0..<youtubeVideoViewModel.youtubeSearchLists[index].items.count, id: \.self) { secondIndex in
                                HStack {
                                    URLImage(url: youtubeVideoViewModel.youtubeSearchLists[index].items[secondIndex].snippet.thumbnails.high?.url ?? "")
                                        .aspectRatio(contentMode: .fit).background(
                                    VStack {
                                            .padding(EdgeInsets(top: 5, leading: 5, bottom: 0, trailing: 5))
                                        Text( youtubeVideoViewModel.youtubeSearchLists[index].items[secondIndex].snippet.description)
                                            .padding(EdgeInsets(top: 5, leading: 5, bottom: 5, trailing: 5))
                                }.frame(width: .none, height: 150, alignment: .center)
                                 .onAppear(perform: {
                                   // Here's the logic for the pagination.
                                   if secondIndex == youtubeVideoViewModel.perPage - 1 && ((youtubeVideoViewModel.youtubeSearchLists.count - 1) == index) {
                                       let pageToken = youtubeVideoViewModel.youtubeSearchLists[index].nextPageToken
                                       youtubeVideoViewModel.fetchVideoWithSearch(searchText: searchText, pageToken: pageToken)
            .navigationTitle("Anime Videos")

Let’s see how it looks. (6).gif

Full code is available at:

In the next episode, I will explain how to play out the video as well as to control play, so stay tuned!