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)
0 Comments:
Post a Comment
Note: Only a member of this blog may post a comment.