Search code examples
swiftswiftuipaginationinfinite-scrollcombine

Pagination & infinity scroll function


i want to write a pagination function that will allow me to have an infinite scrolling but i am finding it quite difficult Bellow is the code for my API call: enter image description here

class CoinDataService: ObservableObject {

@Published var  allCoins: [CoinModel] = []
@Published var isLoading: Bool = false

var coinSubcription: AnyCancellable?

var coinListFull = false

var currentpage = 0

let perpage = 200

var canLoadMorePages = true

init() {
    getCoins()
}

public func getCoins() {
    
    guard !isLoading && canLoadMorePages else {
      return
    }
    
   isLoading = true
    guard let url = URL(string: "https://api.coingecko.com/api/v3/coins/markets?vs_currency=usd&order=market_cap_desc&per_page=\(perpage)&page=\(currentpage)&sparkline=true&price_change_percentage=24h")
    else { return }
    
    coinSubcription = NetworkingManager.download(url: url)
        .decode(type: [CoinModel].self, decoder: JSONDecoder())
        .receive(on: DispatchQueue.main)
        .sink(receiveCompletion: NetworkingManager.handleCompletion, receiveValue: { [weak self] (returnedCoins) in
            self?.allCoins = returnedCoins
            self?.coinSubcription?.cancel()
            if returnedCoins.count < self!.perpage {
                self?.coinListFull = true
            }
        })
    isLoading = false
}

all i need is a function the will allow me to increase the page of my app


Solution

  • Try the following hope it works.

    To implement infinite scrolling with pagination, you can modify your existing code to load more coins when the user reaches the end of the current list. Here's a modified version of your CoinDataService class:

    import Combine
    
    class CoinDataService: ObservableObject {
        @Published var allCoins: [CoinModel] = []
        @Published var isLoading: Bool = false
    
        var coinSubcription: AnyCancellable?
    
        var coinListFull = false
        var currentpage = 1
        let perpage = 200
       var canLoadMorePages = true
    
    init() {
        getCoins()
    }
    
    public func getCoins() {
        guard !isLoading && canLoadMorePages else {
            return
        }
    
        isLoading = true
        guard let url = URL(string: "https://api.coingecko.com/api/v3/coins/markets?vs_currency=usd&order=market_cap_desc&per_page=\(perpage)&page=\(currentpage)&sparkline=true&price_change_percentage=24h")
        else { return }
    
        coinSubcription = NetworkingManager.download(url: url)
            .decode(type: [CoinModel].self, decoder: JSONDecoder())
            .receive(on: DispatchQueue.main)
            .sink(receiveCompletion: { [weak self] completion in
                NetworkingManager.handleCompletion(completion)
                self?.isLoading = false
            }, receiveValue: { [weak self] returnedCoins in
                self?.allCoins.append(contentsOf: returnedCoins)
                if returnedCoins.count < self!.perpage {
                    self?.coinListFull = true
                }
                self?.currentpage += 1
            })
        }
    }
    

    In this modification, I've made the following changes:

    1. Incremented currentpage each time you receive new coins.
    2. Appended the new coins to the existing allCoins array instead of replacing it.
    3. Set isLoading to false in the completion block to indicate the end of the loading process.

    Now, when you call getCoins(), it will fetch the next page of coins and append them to the existing list. You can use this in combination with a SwiftUI List or ScrollView to achieve infinite scrolling. Make sure to handle the loading state appropriately in your UI.