PHPFixing
  • Privacy Policy
  • TOS
  • Ask Question
  • Contact Us
  • Home
  • PHP
  • Programming
  • SQL Injection
  • Web3.0

Thursday, May 19, 2022

[FIXED] How to Increase count of Page in Url for loading more data and show indicator at bottom?

 May 19, 2022     pagination, swift, uiactivityviewcontroller, uitableview, web-services     No comments   

Issue

I Creating a demo of webservices, In this I want to increase page count and load more data from api, and add in table view after activity indicator refreshing. I find many tutorials but Not found useful... They are all Advance and I'm beginner so i didn't get properly. Can Any one please tell how to do this.

Here's My Demo details...

This Is Page Count of URL

 "info": {
    "count": 826,
    "pages": 42,
    "next": "https://rickandmortyapi.com/api/character/?page=3",
    "prev": "https://rickandmortyapi.com/api/character/?page=1"
  },

My json Model

import UIKit
import Foundation

// MARK: - JsonModel
struct JSONModel:Decodable {
let info: Info
let results: [Result]
}

// MARK: - Info
 struct Info : Decodable {
let count, pages: Int
let next: String
let prev: NSNull
 }

  // MARK: - Result
 struct Result : Decodable {
let id: Int
let name: String
let status: Status
let species: Species
let type: String
let gender: Gender
let origin, location: Location
let image: String
let episode: [String]
let url: String
let created: String
 }

enum Gender {
case female
case male
case unknown
 }

// MARK: - Location
struct Location {
let name: String
let url: String
 }

enum Species {
case alien
case human
}

enum Status {
case alive
case dead
case unknown
 }

This is my View controller Class

import UIKit
import Kingfisher

class ViewController: UIViewController,UISearchBarDelegate{



@IBOutlet weak var searchBar: UISearchBar!
@IBOutlet weak var tableView: UITableView!

var results = [Results]()
var filteredData = [Results]()
var batchSize = 42
var fromIndex = 0

override func viewDidLoad() {
    super.viewDidLoad()
    searchBar.delegate = self
    tableView.delegate = self
    tableView.dataSource = self
    apiCalling()
    filteredData = results
    
}

override func viewWillAppear(_ animated: Bool) {
    filteredData = results
    self.tableView.reloadData()
}


func apiCalling(){
    
    
    guard let url = URL(string: "https://rickandmortyapi.com/api/character/") else { return }
    URLSession.shared.dataTask(with: url) {[weak self]data, response, error in
        
        
        if error != nil{
            print("error While Fetching Data")
        }
        
        guard let data = data else {
            return
        }
        do {
            let resultData = try JSONDecoder().decode(JsonModel.self, from: data)
            self?.results = resultData.results!
            self?.filteredData = self!.results
            DispatchQueue.main.async {
                self?.tableView.reloadData()
            }
          
        } catch  {
            print(error.localizedDescription)
        }
    }.resume()

}
func searchBar(_ searchBar: UISearchBar, textDidChange searchText: String) {
   
    let searchText = searchBar.text!
    guard !searchText.isEmpty else {
        filteredData = results
        tableView.reloadData()
        return
    }
    filteredData = results.filter({ $0.name!.lowercased().contains(searchText.lowercased() ) })
    tableView.reloadData()


    }





func searchBarTextDidBeginEditing(_ searchBar: UISearchBar) {
        self.searchBar.showsCancelButton = true
}

func searchBarCancelButtonClicked(_ searchBar: UISearchBar) {
        searchBar.showsCancelButton = false
        searchBar.text = ""
        searchBar.resignFirstResponder()
        filteredData.removeAll()
        self.tableView.reloadData()
   }


 }

This My Tableview Extension

extension ViewController : UITableViewDelegate, UITableViewDataSource  {
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
    return filteredData.count 
}

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
    let cell = tableView.dequeueReusableCell(withIdentifier: "cell") as! UserTableViewCell
    let row = filteredData[indexPath.row]
    let imageUrl = URL(string: row.image!)
    cell.userImage.kf.setImage(with: imageUrl)
    cell.lblGender.text = "Gender:- \(row.gender ?? "no value")"
    cell.lblID.text = "ID:- \(row.id ?? 0)"
    cell.lblName.text = "Name: \(row.name!)"
    cell.lblSpecies.text = "Species:- \(row.species ?? "No Speies")"
    return cell
}
func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
    return UITableView.automaticDimension
    
}

func tableView(_ tableView: UITableView, estimatedHeightForRowAt indexPath: IndexPath) -> CGFloat {
    return 250
}
}

Solution

u need save page info.

self?.info = resultData.info!

call "loadpage" when u loading more data

override func viewDidLoad() {
    super.viewDidLoad()
    searchBar.delegate = self
    tableView.delegate = self
    tableView.dataSource = self
    filteredData = []
    result = []
    apiCalling(apiurl:"https://rickandmortyapi.com/api/character/")
}

func apiCalling(apiurl:String){
    
    
    guard let url = URL(string: apiurl) else { return }
    URLSession.shared.dataTask(with: url) {[weak self]data, response, error in
        
        
        if error != nil{
            print("error While Fetching Data")
        }
        
        guard let data = data else {
            return
        }
        do {
            let resultData = try JSONDecoder().decode(JsonModel.self, from: data)
            self?.results.append(resultData.results!)
            self?.info = resultData.info!
            filterWord()
          
        } catch  {
            print(error.localizedDescription)
        }
    }.resume()

}

func filterWord(){
    let searchText = searchBar.text!
    guard !searchText.isEmpty else {
        filteredData = results
        tableView.reloadData()
        return
    }
    filteredData = results.filter({ $0.name!.lowercased().contains(searchText.lowercased() ) })
    tableView.reloadData()
}

func loadPage(){
    guard let page = self?.info.next,!page.isEmpty else{
        return
    }
    apiCalling(apiurl:page)
}

under indicator simple example like this

func tableView(_ tableView: UITableView, viewForFooterInSection section: Int) -> UIView? {
    guard let page = self?.info.next,!page.isEmpty else{
        return nil
    }
    //press to call loadPage
    let loading = UIButton.init()
    let view = UIView.init()
    view.addSubview(loading)
    return view
}


Answered By - Leo Chen
Answer Checked By - Gilberto Lyons (PHPFixing Admin)
  • Share This:  
  •  Facebook
  •  Twitter
  •  Stumble
  •  Digg
Newer Post Older Post Home

0 Comments:

Post a Comment

Note: Only a member of this blog may post a comment.

Total Pageviews

Featured Post

Why Learn PHP Programming

Why Learn PHP Programming A widely-used open source scripting language PHP is one of the most popular programming languages in the world. It...

Subscribe To

Posts
Atom
Posts
Comments
Atom
Comments

Copyright © PHPFixing